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_move.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 common to
   61  *        translations that move data (i.e. read, write).  It has code for
   62  *        the various different size CDBs (6, 10, 12, 16).
   63  */
   64 
   65 #include <dev/isci/scil/sati_move.h>
   66 #include <dev/isci/scil/sati_callbacks.h>
   67 #include <dev/isci/scil/sati_translator_sequence.h>
   68 #include <dev/isci/scil/sati_util.h>
   69 #include <dev/isci/scil/intel_ata.h>
   70 #include <dev/isci/scil/intel_scsi.h>
   71 #include <dev/isci/scil/intel_sat.h>
   72 
   73 //******************************************************************************
   74 //* P R I V A T E   M E T H O D S
   75 //******************************************************************************
   76 
   77 /**
   78  * @brief This method simply sets the command register based upon the
   79  *        supplied opcodes and the data direction.
   80  *        For more information on the parameters passed to this method,
   81  *        please reference sati_translate_command()
   82  *
   83  * @param[in] write_opcode This parameter specifies the value to be written
   84  *            to the ATA command register for a write (data out) operation.
   85  * @param[in] read_opcode This parameter specifies the value to be written
   86  *            to the ATA command register for a read (data in) operation.
   87  *
   88  * @return none.
   89  */
   90 static
   91 void sati_move_set_ata_command(
   92    SATI_TRANSLATOR_SEQUENCE_T * sequence,
   93    void                       * ata_io,
   94    U8                           write_opcode,
   95    U8                           read_opcode
   96 )
   97 {
   98    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
   99 
  100    if (sequence->data_direction == SATI_DATA_DIRECTION_OUT)
  101       sati_set_ata_command(register_fis, write_opcode);
  102    else
  103       sati_set_ata_command(register_fis, read_opcode);
  104 }
  105 
  106 /**
  107  * @brief This method will translate the SCSI transfer count from the 6-byte
  108  *        CDB into the appropriate amount in the ATA register FIS.  Please
  109  *        note for 48-bit UDMA requests, the caller must set the sector
  110  *        count extended field.  This method also sets protocol and
  111  *        command fields.
  112  *        For more information on the parameters passed to this method,
  113  *        please reference sati_translate_command()
  114  *
  115  * @param[in] write_opcode This parameter specifies the value to be written
  116  *            to the ATA command register for a write (data out) operation.
  117  * @param[in] read_opcode This parameter specifies the value to be written
  118  *            to the ATA command register for a read (data in) operation.
  119  *
  120  * @return none
  121  */
  122 static
  123 void sati_move_small_udma_translate_command(
  124    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  125    void                       * scsi_io,
  126    void                       * ata_io,
  127    U8                           write_opcode,
  128    U8                           read_opcode
  129 )
  130 {
  131    U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
  132    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
  133 
  134    sati_move_set_ata_command(sequence, ata_io, write_opcode, read_opcode);
  135    sati_set_ata_sector_count(register_fis, sati_get_cdb_byte(cdb, 4));
  136 
  137    if (sequence->data_direction == SATI_DATA_DIRECTION_IN)
  138       sequence->protocol = SAT_PROTOCOL_UDMA_DATA_IN;
  139    else
  140       sequence->protocol = SAT_PROTOCOL_UDMA_DATA_OUT;
  141 }
  142 
  143 /**
  144  * @brief This method will translate the SCSI transfer count from the
  145  *        supplied sector_count parameter into the ATA register FIS.
  146  *        The translation is specific to 10,12, 16 byte CDBs.
  147  *        This method also sets protocol and command fields.
  148  *        For more information on the parameters passed to this method,
  149  *        please reference sati_translate_command()
  150  *
  151  * @param[in] sector_count This parameter specifies the number of sectors
  152  *            to be transferred.
  153  * @param[in] write_opcode This parameter specifies the value to be written
  154  *            to the ATA command register for a write (data out) operation.
  155  * @param[in] read_opcode This parameter specifies the value to be written
  156  *            to the ATA command register for a read (data in) operation.
  157  *
  158  * @return Please reference sati_move_set_sector_count() for information
  159  *         on return codes from this method.
  160  */
  161 static
  162 SATI_STATUS sati_move_large_udma_translate_command(
  163    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  164    void                       * scsi_io,
  165    void                       * ata_io,
  166    U32                          sector_count,
  167    U8                           write_opcode,
  168    U8                           read_opcode
  169 )
  170 {
  171    sati_move_set_ata_command(sequence, ata_io, write_opcode, read_opcode);
  172 
  173    if (sequence->data_direction == SATI_DATA_DIRECTION_IN)
  174       sequence->protocol = SAT_PROTOCOL_UDMA_DATA_IN;
  175    else
  176       sequence->protocol = SAT_PROTOCOL_UDMA_DATA_OUT;
  177 
  178    return sati_move_set_sector_count(
  179              sequence, scsi_io, ata_io, sector_count, FALSE
  180           );
  181 }
  182 
  183 /**
  184  * @brief This method will translate the SCSI transfer count from the 6-byte
  185  *        CDB into the appropriate amount in the ATA register FIS.
  186  *        This is only used for translation of 6-byte SCSI CDBs.
  187  *        For more information on the parameters passed to this method,
  188  *        please reference sati_translate_command()
  189  *
  190  * @return none
  191  */
  192 static
  193 void sati_move_ncq_translate_8_bit_sector_count(
  194    void * scsi_io,
  195    void * ata_io
  196 )
  197 {
  198    U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
  199    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
  200 
  201    sati_set_ata_features(register_fis, sati_get_cdb_byte(cdb, 4));
  202 
  203    // A read 6 with a 0 sector count indicates a transfer of 256 sectors.
  204    // As a result update the MSB (features expanded register) to indicate
  205    // 256 sectors (0x100).
  206    if (sati_get_cdb_byte(cdb, 4) == 0)
  207       sati_set_ata_features_exp(register_fis, 1);
  208 }
  209 
  210 //******************************************************************************
  211 //* P U B L I C   M E T H O D S
  212 //******************************************************************************
  213 
  214 /**
  215  * @brief This method will process a 32-bit sector into the appropriate fields
  216  *        in a register FIS.  This method works for both 8-bit and 16-bit sector
  217  *        counts.
  218  *        This is used for translation of 10, 12, and 16-byte SCSI CDBs.
  219  *        For more information on the parameters passed to this method,
  220  *        please reference sati_translate_command().
  221  *
  222  * @note This method should only be called for CDB sizes of 10-bytes or larger.
  223  *
  224  * @param[in] sector_count This parameter specifies the number of sectors
  225  *            to be transferred.
  226  * @param[in] is_fpdma_command This parameter indicates if the supplied
  227  *            ata_io is a first party DMA request (NCQ).
  228  *
  229  * @return none
  230  */
  231 SATI_STATUS sati_move_set_sector_count(
  232    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  233    void                       * scsi_io,
  234    void                       * ata_io,
  235    U32                          sector_count,
  236    U8                           is_fpdma_command
  237 )
  238 {
  239    U32  max_sector_count;
  240    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
  241 
  242    if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE)
  243       max_sector_count = 65536;
  244    else
  245       max_sector_count = 256;
  246 
  247    // Check the CDB transfer length count and set the register FIS sector
  248    // count fields
  249    if (0 == sector_count)
  250    {
  251       // A SCSI sector count of 0 for 10-byte CDBs and larger indicate no data
  252       // transfer, so simply complete the command immediately.
  253       return SATI_COMPLETE;
  254    }
  255    else if (sector_count >= max_sector_count)
  256    {
  257       // We have to perform multiple SATA commands to satisfy the sector
  258       // count specified in the SCSI command.
  259       sequence->command_specific_data.move_sector_count =
  260          sector_count - max_sector_count;
  261 
  262       // In ATA a sector count of 0 indicates use the maximum allowed for
  263       // the command (i.e. 0 == 2^16 or 2^8).
  264       sector_count = 0;
  265    }
  266 
  267    if (is_fpdma_command)
  268    {
  269       sati_set_ata_features(register_fis, sector_count & 0xFF);
  270       sati_set_ata_features_exp(register_fis, (sector_count >> 8) & 0xFF);
  271    }
  272    else
  273    {
  274       sati_set_ata_sector_count(register_fis, sector_count & 0xFF);
  275       sati_set_ata_sector_count_exp(register_fis, (sector_count >> 8) & 0xFF);
  276    }
  277 
  278    return SATI_SUCCESS;
  279 }
  280 
  281 /**
  282  * @brief This method simply translates the 32-bit logical block address
  283  *        field from the SCSI CDB (10 or 12-byte) into the ATA task
  284  *        file (register FIS).
  285  *        For more information on the parameters passed to this method,
  286  *        please reference sati_translate_command()
  287  *
  288  * @return none
  289  */
  290 void sati_move_translate_32_bit_lba(
  291    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  292    void                       * scsi_io,
  293    void                       * ata_io
  294 )
  295 {
  296    U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
  297    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
  298 
  299    sati_set_ata_lba_low(register_fis, sati_get_cdb_byte(cdb, 5));
  300    sati_set_ata_lba_mid(register_fis, sati_get_cdb_byte(cdb, 4));
  301    sati_set_ata_lba_high(register_fis, sati_get_cdb_byte(cdb, 3));
  302    sati_set_ata_lba_low_exp(register_fis, sati_get_cdb_byte(cdb, 2));
  303    sati_set_ata_lba_mid_exp(register_fis, 0);
  304    sati_set_ata_lba_high_exp(register_fis, 0);
  305 }
  306 
  307 /**
  308  * @brief This method simply translates the 64-bit logical block address
  309  *        field from the SCSI CDB (16 byte) into the ATA task
  310  *        file (register FIS).  The 2 most significant bytes must be 0,
  311  *        since ATA devices can, at most, support 48-bits of LBA.
  312  *        For more information on the parameters passed to this method,
  313  *        please reference sati_translate_command()
  314  *
  315  * @return Indicate if the LBA translation succeeded.
  316  * @return SATI_SUCCESS This is returned if translation was successful.
  317  * @return SATI_FAILURE_CHECK_RESPONSE_DATA This is returned if either
  318  *         of the 2 most significant bytes contain a non-zero value.
  319  */
  320 SATI_STATUS sati_move_translate_64_bit_lba(
  321    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  322    void                       * scsi_io,
  323    void                       * ata_io
  324 )
  325 {
  326    U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
  327    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
  328 
  329    // Ensure we receive a logical block address that is within range of
  330    // addressibility per the ATA specification (i.e. 48-bit or 28-bit).
  331    if ( (sati_get_cdb_byte(cdb, 2) == 0) && (sati_get_cdb_byte(cdb, 3) == 0) )
  332    {
  333       sati_set_ata_lba_low(register_fis, sati_get_cdb_byte(cdb, 9));
  334       sati_set_ata_lba_mid(register_fis, sati_get_cdb_byte(cdb, 8));
  335       sati_set_ata_lba_high(register_fis, sati_get_cdb_byte(cdb, 7));
  336       sati_set_ata_lba_low_exp(register_fis, sati_get_cdb_byte(cdb, 6));
  337       sati_set_ata_lba_mid_exp(register_fis, sati_get_cdb_byte(cdb, 5));
  338       sati_set_ata_lba_high_exp(register_fis, sati_get_cdb_byte(cdb, 4));
  339       return SATI_SUCCESS;
  340    }
  341    else
  342    {
  343       sati_scsi_sense_data_construct(
  344          sequence,
  345          scsi_io,
  346          SCSI_STATUS_CHECK_CONDITION,
  347          SCSI_SENSE_ILLEGAL_REQUEST,
  348          SCSI_ASC_LBA_OUT_OF_RANGE,
  349          SCSI_ASCQ_LBA_OUT_OF_RANGE
  350       );
  351       return SATI_FAILURE_CHECK_RESPONSE_DATA;
  352    }
  353 }
  354 
  355 /**
  356  * @brief This method will translate the pieces common to SCSI read and
  357  *        write 6 byte commands.  Depending upon the capabilities
  358  *        supported by the target different ATA commands can be selected.
  359  *        For more information on the parameters passed to this method,
  360  *        please reference sati_translate_command().
  361  *
  362  * @return Indicate if the command translation succeeded.
  363  * @retval SCI_SUCCESS This is returned if the command translation was
  364  *         successful.
  365  */
  366 SATI_STATUS sati_move_6_translate_command(
  367    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  368    void                       * scsi_io,
  369    void                       * ata_io
  370 )
  371 {
  372    U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
  373    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
  374 
  375    // Translate the logical block address information from the SCSI CDB.
  376    // There is only 5 bits of MSB located in byte 1 of the CDB.
  377    sati_set_ata_lba_low(register_fis, sati_get_cdb_byte(cdb, 3));
  378    sati_set_ata_lba_mid(register_fis, sati_get_cdb_byte(cdb, 2));
  379    sati_set_ata_lba_high(register_fis, sati_get_cdb_byte(cdb, 1) & 0x1F);
  380 
  381    sati_move_translate_command(sequence, scsi_io, ata_io, 0);
  382 
  383    return SATI_SUCCESS;
  384 }
  385 
  386 /**
  387  * @brief This method will translate the pieces common to SCSI read and
  388  *        write 10/12 byte commands.  Depending upon the capabilities
  389  *        supported by the target different ATA commands can be selected.
  390  *        For more information on the parameters passed to this method,
  391  *        please reference sati_translate_command().
  392  *
  393  * @param[in] device_head This parameter specifies the contents to be
  394  *            written to the device head register.
  395  *
  396  * @return Indicate if the command translation succeeded.
  397  * @retval SCI_SUCCESS This is returned if the command translation was
  398  *         successful.
  399  */
  400 SATI_STATUS sati_move_32_bit_lba_translate_command(
  401    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  402    void                       * scsi_io,
  403    void                       * ata_io,
  404    U8                           device_head
  405 )
  406 {
  407    sati_move_translate_32_bit_lba(sequence, scsi_io, ata_io);
  408    sati_move_translate_command(sequence, scsi_io, ata_io, device_head);
  409 
  410    return SATI_SUCCESS;
  411 }
  412 
  413 /**
  414  * @brief This method provides the common translation functionality for
  415  *        the 6-byte move command descriptor blocks (CDBs).
  416  *        This method will ensure that the following is performed:
  417  *        - command register is set
  418  *        - the SATI_TRANSLATOR_SEQUENCE::protocol field is set
  419  *        - the sector count field(s) are set
  420  *        - sati_move_6_translate_command() is invoked.
  421  *        For more information on the parameters passed to this method,
  422  *        please reference sati_translate_command().
  423  *
  424  * @pre The caller must ensure that the
  425  *      SATI_TRANSLATOR_SEQUENCE::data_direction field has already been set.
  426  *
  427  * @return Indicate if the command translation succeeded.
  428  * @see sati_move_6_translate_command() for additional return codes.
  429  */
  430 SATI_STATUS sati_move_small_translate_command(
  431    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  432    void                       * scsi_io,
  433    void                       * ata_io
  434 )
  435 {
  436    // Translation of the sector count is performed differently for NCQ vs.
  437    // other protocols.
  438    if (sequence->device->capabilities & SATI_DEVICE_CAP_NCQ_SUPPORTED_ENABLE)
  439    {
  440       sati_move_set_ata_command(
  441          sequence, ata_io, ATA_WRITE_FPDMA, ATA_READ_FPDMA
  442       );
  443       sati_move_ncq_translate_8_bit_sector_count(scsi_io, ata_io);
  444       sequence->protocol = SAT_PROTOCOL_FPDMA;
  445    }
  446    else if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE)
  447    {
  448       U8 * cdb = sati_cb_get_cdb_address(scsi_io);
  449 
  450       sati_move_small_udma_translate_command(
  451          sequence, scsi_io, ata_io, ATA_WRITE_DMA_EXT, ATA_READ_DMA_EXT
  452       );
  453 
  454       // A read/write 6 with a 0 sector count indicates a transfer of 256
  455       // sectors.  As a result update the MSB (features expanded register)
  456       // to indicate 256 sectors (0x100).
  457       if (sati_get_cdb_byte(cdb, 4) == 0)
  458       {
  459          U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
  460          sati_set_ata_sector_count_exp(register_fis, 1);
  461       }
  462    }
  463    else if (sequence->device->capabilities & SATI_DEVICE_CAP_UDMA_ENABLE)
  464    {
  465       sati_move_small_udma_translate_command(
  466          sequence, scsi_io, ata_io, ATA_WRITE_DMA, ATA_READ_DMA
  467       );
  468    }
  469    else
  470    {
  471       /**
  472        * Currently the translation does not support devices incapable of
  473        * handling the 48-bit feature set (i.e. 16 bits of sector count).
  474        */
  475       sati_scsi_sense_data_construct(
  476          sequence,
  477          scsi_io,
  478          SCSI_STATUS_CHECK_CONDITION,
  479          SCSI_SENSE_ILLEGAL_REQUEST,
  480          SCSI_ASC_INVALID_FIELD_IN_CDB,
  481          SCSI_ASCQ_INVALID_FIELD_IN_CDB
  482       );
  483       return SATI_FAILURE_CHECK_RESPONSE_DATA;
  484    }
  485 
  486    return sati_move_6_translate_command(sequence, scsi_io, ata_io);
  487 }
  488 
  489 /**
  490  * @brief This method provides the common translation functionality for
  491  *        the larger command descriptor blocks (10, 12, 16-byte CDBs).
  492  *        For more information on the parameters passed to this method,
  493  *        please reference sati_translate_command().
  494  *
  495  * @param[in] sector_count This parameter specifies the number of sectors
  496  *            to be transferred.
  497  * @param[in] device_head This parameter specifies the contents to be
  498  *            written to the device head register.
  499  *
  500  * @return Indicate if the command translation succeeded.
  501  * @retval SATI_FAILURE This value is returned if neither NCQ or DMA is
  502  *         supported by the target device.
  503  * @see sati_move_set_sector_count() for additional return codes.
  504  */
  505 SATI_STATUS sati_move_large_translate_command(
  506    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  507    void                       * scsi_io,
  508    void                       * ata_io,
  509    U32                          sector_count,
  510    U8                         * ata_device_head
  511 )
  512 {
  513    SATI_STATUS   status = SATI_SUCCESS;
  514    U8          * cdb    = sati_cb_get_cdb_address(scsi_io);
  515 
  516    // Parts of translation (e.g. sector count) is performed differently
  517    // for NCQ vs. other protocols.
  518    if (sequence->device->capabilities & SATI_DEVICE_CAP_NCQ_SUPPORTED_ENABLE)
  519    {
  520       // if the user did not request to ignore FUA
  521       if((sequence->device->capabilities & SATI_DEVICE_CAP_IGNORE_FUA)==0)
  522       {
  523          // Is the Force Unit Access bit set?
  524          if (sati_get_cdb_byte(cdb, 1) & SCSI_MOVE_FUA_BIT_ENABLE)
  525             *ata_device_head = ATA_DEV_HEAD_REG_FUA_ENABLE;
  526       }
  527 
  528       sati_move_set_ata_command(
  529          sequence, ata_io, ATA_WRITE_FPDMA, ATA_READ_FPDMA
  530       );
  531       status = sati_move_set_sector_count(
  532                   sequence, scsi_io, ata_io, sector_count, TRUE
  533                );
  534       sequence->protocol = SAT_PROTOCOL_FPDMA;
  535    }
  536    else if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE)
  537    {
  538       // Is the Force Unit Access bit set?  If it is, then error.  We
  539       // aren't supporting this yet for normal DMA.
  540       if (sati_get_cdb_byte(cdb, 1) & SCSI_MOVE_FUA_BIT_ENABLE)
  541       {
  542          sati_scsi_sense_data_construct(
  543             sequence,
  544             scsi_io,
  545             SCSI_STATUS_CHECK_CONDITION,
  546             SCSI_SENSE_ILLEGAL_REQUEST,
  547             SCSI_ASC_INVALID_FIELD_IN_CDB,
  548             SCSI_ASCQ_INVALID_FIELD_IN_CDB
  549          );
  550          return SATI_FAILURE_CHECK_RESPONSE_DATA;
  551       }
  552 
  553       status = sati_move_large_udma_translate_command(
  554                   sequence,
  555                   scsi_io,
  556                   ata_io,
  557                   sector_count,
  558                   ATA_WRITE_DMA_EXT,
  559                   ATA_READ_DMA_EXT
  560                );
  561    }
  562    else if (sequence->device->capabilities & SATI_DEVICE_CAP_UDMA_ENABLE)
  563    {
  564       status = sati_move_large_udma_translate_command(
  565                   sequence,
  566                   scsi_io,
  567                   ata_io,
  568                   sector_count,
  569                   ATA_WRITE_DMA,
  570                   ATA_READ_DMA
  571                );
  572    }
  573    else
  574    {
  575       /**
  576        * Currently the translation does not support devices incapable of
  577        * handling the 48-bit feature set (i.e. 16 bits of sector count).
  578        */
  579       sati_scsi_sense_data_construct(
  580          sequence,
  581          scsi_io,
  582          SCSI_STATUS_CHECK_CONDITION,
  583          SCSI_SENSE_ILLEGAL_REQUEST,
  584          SCSI_ASC_INVALID_FIELD_IN_CDB,
  585          SCSI_ASCQ_INVALID_FIELD_IN_CDB
  586       );
  587       return SATI_FAILURE_CHECK_RESPONSE_DATA;
  588    }
  589 
  590    return status;
  591 }
  592 
  593 /**
  594  * @brief This method simply performs the functionality common to all
  595  *        payload data movement translations (i.e. READ/WRITE).
  596  *        For more information on the parameters passed to this method,
  597  *        please reference sati_translate_command().
  598  *
  599  * @param[in] device_head This parameter specifies the current contents
  600  *            to be written to the ATA task file (register FIS) device
  601  *            head register.
  602  *
  603  * @return none
  604  */
  605 void sati_move_translate_command(
  606    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  607    void                       * scsi_io,
  608    void                       * ata_io,
  609    U8                           device_head
  610 )
  611 {
  612    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
  613 
  614    sati_set_ata_device_head(
  615       register_fis, device_head | ATA_DEV_HEAD_REG_LBA_MODE_ENABLE
  616    );
  617 }
  618 

Cache object: c4af4774c66e9f3f1896298ec8c43a15


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