2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 #include <sys/cdefs.h>
54 __FBSDID("$FreeBSD$");
58 * @brief This file contains the method implementations for translating
59 * the SCSI VERIFY (10, 12, 16-byte) commands.
62 #if !defined(DISABLE_SATI_VERIFY)
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>
69 #include <dev/isci/scil/intel_ata.h>
70 #include <dev/isci/scil/intel_scsi.h>
71 #include <dev/isci/scil/intel_sat.h>
73 //******************************************************************************
74 //* P R I V A T E M E T H O D S
75 //******************************************************************************
78 * @brief This method performs the SCSI VERIFY command translation
79 * functionality common to all VERIFY command sizes.
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().
87 * @return Indicate if the method was successfully completed.
88 * @retval SATI_SUCCESS This is returned in all other cases.
91 SATI_STATUS sati_verify_translate_command(
92 SATI_TRANSLATOR_SEQUENCE_T * sequence,
97 U8 * cdb = sati_cb_get_cdb_address(scsi_io);
98 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
101 * The translator doesn't support performing the byte check operation.
102 * As a result, error the request if the BYTCHK bit is set.
104 if ((sati_get_cdb_byte(cdb, 1) & SCSI_VERIFY_BYTCHK_ENABLED))
106 sati_scsi_sense_data_construct(
109 SCSI_STATUS_CHECK_CONDITION,
110 SCSI_SENSE_ILLEGAL_REQUEST,
111 SCSI_ASC_INVALID_FIELD_IN_CDB,
112 SCSI_ASCQ_INVALID_FIELD_IN_CDB
114 return SATI_FAILURE_CHECK_RESPONSE_DATA;
117 sequence->protocol = SAT_PROTOCOL_NON_DATA;
118 sequence->data_direction = SATI_DATA_DIRECTION_NONE;
120 sati_set_ata_device_head(register_fis, ATA_DEV_HEAD_REG_LBA_MODE_ENABLE);
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);
126 sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS);
131 //******************************************************************************
132 //* P U B L I C M E T H O D S
133 //******************************************************************************
136 * @brief This method performs all of the translation required for a
137 * SCSI VERIFY 10 byte CDB.
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().
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()
149 SATI_STATUS sati_verify_10_translate_command(
150 SATI_TRANSLATOR_SEQUENCE_T * sequence,
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));
160 if(sati_device_state_stopped(sequence, scsi_io))
162 return SATI_FAILURE_CHECK_RESPONSE_DATA;
166 sequence->type = SATI_SEQUENCE_VERIFY_10;
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)
174 return sati_verify_translate_command(sequence, scsi_io, ata_io);
179 * @brief This method performs all of the translation required for a
180 * SCSI VERIFY 12 byte CDB.
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().
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()
192 SATI_STATUS sati_verify_12_translate_command(
193 SATI_TRANSLATOR_SEQUENCE_T * sequence,
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));
205 if(sati_device_state_stopped(sequence, scsi_io))
207 return SATI_FAILURE_CHECK_RESPONSE_DATA;
211 sequence->type = SATI_SEQUENCE_VERIFY_12;
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)
219 return sati_verify_translate_command(sequence, scsi_io, ata_io);
224 * @brief This method performs all of the translation required for a
225 * SCSI VERIFY 16 byte CDB.
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().
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()
237 SATI_STATUS sati_verify_16_translate_command(
238 SATI_TRANSLATOR_SEQUENCE_T * sequence,
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));
250 if(sati_device_state_stopped(sequence, scsi_io))
252 return SATI_FAILURE_CHECK_RESPONSE_DATA;
256 sequence->type = SATI_SEQUENCE_VERIFY_16;
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)
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)
268 return sati_verify_translate_command(sequence, scsi_io, ata_io);
272 #endif // !defined(DISABLE_SATI_VERIFY)