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