xref: /freebsd/sys/dev/isci/scil/sati_verify.c (revision 0957b409)
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 for translating
61  *        the SCSI VERIFY (10, 12, 16-byte) commands.
62  */
63 
64 #if !defined(DISABLE_SATI_VERIFY)
65 
66 #include <dev/isci/scil/sati_verify.h>
67 #include <dev/isci/scil/sati_callbacks.h>
68 #include <dev/isci/scil/sati_util.h>
69 #include <dev/isci/scil/sati_move.h>
70 
71 #include <dev/isci/scil/intel_ata.h>
72 #include <dev/isci/scil/intel_scsi.h>
73 #include <dev/isci/scil/intel_sat.h>
74 
75 //******************************************************************************
76 //* P R I V A T E   M E T H O D S
77 //******************************************************************************
78 
79 /**
80  * @brief This method performs the SCSI VERIFY command translation
81  *        functionality common to all VERIFY command sizes.
82  *        This includes:
83  *        - setting the command register
84  *        - setting the device head register
85  *        - filling in fields in the SATI_TRANSLATOR_SEQUENCE object.
86  *        For more information on the parameters passed to this method,
87  *        please reference sati_translate_command().
88  *
89  * @return Indicate if the method was successfully completed.
90  * @retval SATI_SUCCESS This is returned in all other cases.
91  */
92 static
93 SATI_STATUS sati_verify_translate_command(
94    SATI_TRANSLATOR_SEQUENCE_T * sequence,
95    void                       * scsi_io,
96    void                       * ata_io
97 )
98 {
99    U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
100    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
101 
102    /**
103     * The translator doesn't support performing the byte check operation.
104     * As a result, error the request if the BYTCHK bit is set.
105     */
106    if ((sati_get_cdb_byte(cdb, 1) & SCSI_VERIFY_BYTCHK_ENABLED))
107    {
108       sati_scsi_sense_data_construct(
109          sequence,
110          scsi_io,
111          SCSI_STATUS_CHECK_CONDITION,
112          SCSI_SENSE_ILLEGAL_REQUEST,
113          SCSI_ASC_INVALID_FIELD_IN_CDB,
114          SCSI_ASCQ_INVALID_FIELD_IN_CDB
115       );
116       return SATI_FAILURE_CHECK_RESPONSE_DATA;
117    }
118 
119    sequence->protocol       = SAT_PROTOCOL_NON_DATA;
120    sequence->data_direction = SATI_DATA_DIRECTION_NONE;
121 
122    sati_set_ata_device_head(register_fis, ATA_DEV_HEAD_REG_LBA_MODE_ENABLE);
123 
124    // Ensure the device supports the 48 bit feature set.
125    if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE)
126       sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS_EXT);
127    else
128       sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS);
129 
130    return SATI_SUCCESS;
131 }
132 
133 //******************************************************************************
134 //* P U B L I C   M E T H O D S
135 //******************************************************************************
136 
137 /**
138  * @brief This method performs all of the translation required for a
139  *        SCSI VERIFY 10 byte CDB.
140  *        This includes:
141  *        - logical block address translation
142  *        - transfer length (sector count) translation
143  *        - translation items common to all VERIFY CDB sizes.
144  *        For more information on the parameters passed to this method,
145  *        please reference sati_translate_command().
146  *
147  * @return Indicate if the command translation was successful.
148  *         For more information on return values please reference
149  *         sati_move_set_sector_count(), sati_verify_translate_command()
150  */
151 SATI_STATUS sati_verify_10_translate_command(
152    SATI_TRANSLATOR_SEQUENCE_T * sequence,
153    void                       * scsi_io,
154    void                       * ata_io
155 )
156 {
157    SATI_STATUS   status;
158    U8          * cdb          = sati_cb_get_cdb_address(scsi_io);
159    U32           sector_count = (sati_get_cdb_byte(cdb, 7) << 8) |
160                                 (sati_get_cdb_byte(cdb, 8));
161 
162    if(sati_device_state_stopped(sequence, scsi_io))
163    {
164       return SATI_FAILURE_CHECK_RESPONSE_DATA;
165    }
166    else
167    {
168       sequence->type = SATI_SEQUENCE_VERIFY_10;
169 
170       // Fill in the Logical Block Address fields and sector count registers.
171       sati_move_translate_32_bit_lba(sequence, scsi_io, ata_io);
172       status = sati_move_set_sector_count(sequence,scsi_io,ata_io,sector_count,0);
173       if (status != SATI_SUCCESS)
174          return status;
175 
176       return sati_verify_translate_command(sequence, scsi_io, ata_io);
177    }
178 }
179 
180 /**
181  * @brief This method performs all of the translation required for a
182  *        SCSI VERIFY 12 byte CDB.
183  *        This includes:
184  *        - logical block address translation
185  *        - transfer length (sector count) translation
186  *        - translation items common to all VERIFY CDB sizes.
187  *        For more information on the parameters passed to this method,
188  *        please reference sati_translate_command().
189  *
190  * @return Indicate if the command translation was successful.
191  *         For more information on return values please reference
192  *         sati_move_set_sector_count(), sati_verify_translate_command()
193  */
194 SATI_STATUS sati_verify_12_translate_command(
195    SATI_TRANSLATOR_SEQUENCE_T * sequence,
196    void                       * scsi_io,
197    void                       * ata_io
198 )
199 {
200    SATI_STATUS   status;
201    U8          * cdb          = sati_cb_get_cdb_address(scsi_io);
202    U32           sector_count = (sati_get_cdb_byte(cdb, 6) << 24) |
203                                 (sati_get_cdb_byte(cdb, 7) << 16) |
204                                 (sati_get_cdb_byte(cdb, 8) << 8)  |
205                                 (sati_get_cdb_byte(cdb, 9));
206 
207    if(sati_device_state_stopped(sequence, scsi_io))
208    {
209       return SATI_FAILURE_CHECK_RESPONSE_DATA;
210    }
211    else
212    {
213       sequence->type = SATI_SEQUENCE_VERIFY_12;
214 
215       // Fill in the Logical Block Address fields and sector count registers.
216       sati_move_translate_32_bit_lba(sequence, scsi_io, ata_io);
217       status = sati_move_set_sector_count(sequence,scsi_io,ata_io,sector_count,0);
218       if (status != SATI_SUCCESS)
219          return status;
220 
221       return sati_verify_translate_command(sequence, scsi_io, ata_io);
222    }
223 }
224 
225 /**
226  * @brief This method performs all of the translation required for a
227  *        SCSI VERIFY 16 byte CDB.
228  *        This includes:
229  *        - logical block address translation
230  *        - transfer length (sector count) translation
231  *        - translation items common to all VERIFY CDB sizes.
232  *        For more information on the parameters passed to this method,
233  *        please reference sati_translate_command().
234  *
235  * @return Indicate if the command translation was successful.
236  *         For more information on return values please reference
237  *         sati_move_set_sector_count(), sati_verify_translate_command()
238  */
239 SATI_STATUS sati_verify_16_translate_command(
240    SATI_TRANSLATOR_SEQUENCE_T * sequence,
241    void                       * scsi_io,
242    void                       * ata_io
243 )
244 {
245    SATI_STATUS   status;
246    U8          * cdb          = sati_cb_get_cdb_address(scsi_io);
247    U32           sector_count = (sati_get_cdb_byte(cdb, 10) << 24) |
248                                 (sati_get_cdb_byte(cdb, 11) << 16) |
249                                 (sati_get_cdb_byte(cdb, 12) << 8)  |
250                                 (sati_get_cdb_byte(cdb, 13));
251 
252    if(sati_device_state_stopped(sequence, scsi_io))
253    {
254       return SATI_FAILURE_CHECK_RESPONSE_DATA;
255    }
256    else
257    {
258       sequence->type = SATI_SEQUENCE_VERIFY_16;
259 
260       // Fill in the Logical Block Address field.
261       status = sati_move_translate_64_bit_lba(sequence, scsi_io, ata_io);
262       if (status != SATI_SUCCESS)
263          return status;
264 
265       // Fill in the Sector Count fields.
266       status = sati_move_set_sector_count(sequence,scsi_io,ata_io,sector_count,0);
267       if (status != SATI_SUCCESS)
268          return status;
269 
270       return sati_verify_translate_command(sequence, scsi_io, ata_io);
271    }
272 }
273 
274 #endif // !defined(DISABLE_SATI_VERIFY)
275 
276