1230557Sjimharris/*-
2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license.  When using or
3230557Sjimharris * redistributing this file, you may do so under either license.
4230557Sjimharris *
5230557Sjimharris * GPL LICENSE SUMMARY
6230557Sjimharris *
7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8230557Sjimharris *
9230557Sjimharris * This program is free software; you can redistribute it and/or modify
10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as
11230557Sjimharris * published by the Free Software Foundation.
12230557Sjimharris *
13230557Sjimharris * This program is distributed in the hope that it will be useful, but
14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of
15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16230557Sjimharris * General Public License for more details.
17230557Sjimharris *
18230557Sjimharris * You should have received a copy of the GNU General Public License
19230557Sjimharris * along with this program; if not, write to the Free Software
20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21230557Sjimharris * The full GNU General Public License is included in this distribution
22230557Sjimharris * in the file called LICENSE.GPL.
23230557Sjimharris *
24230557Sjimharris * BSD LICENSE
25230557Sjimharris *
26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27230557Sjimharris * All rights reserved.
28230557Sjimharris *
29230557Sjimharris * Redistribution and use in source and binary forms, with or without
30230557Sjimharris * modification, are permitted provided that the following conditions
31230557Sjimharris * are met:
32230557Sjimharris *
33230557Sjimharris *   * Redistributions of source code must retain the above copyright
34230557Sjimharris *     notice, this list of conditions and the following disclaimer.
35230557Sjimharris *   * Redistributions in binary form must reproduce the above copyright
36230557Sjimharris *     notice, this list of conditions and the following disclaimer in
37230557Sjimharris *     the documentation and/or other materials provided with the
38230557Sjimharris *     distribution.
39230557Sjimharris *
40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51230557Sjimharris */
52230557Sjimharris
53230557Sjimharris#include <sys/cdefs.h>
54230557Sjimharris__FBSDID("$FreeBSD$");
55230557Sjimharris
56230557Sjimharris/**
57230557Sjimharris * @file
58230557Sjimharris * @brief This file contains the method implementations for translating
59230557Sjimharris *        the SCSI VERIFY (10, 12, 16-byte) commands.
60230557Sjimharris */
61230557Sjimharris
62230557Sjimharris#if !defined(DISABLE_SATI_VERIFY)
63230557Sjimharris
64230557Sjimharris#include <dev/isci/scil/sati_verify.h>
65230557Sjimharris#include <dev/isci/scil/sati_callbacks.h>
66230557Sjimharris#include <dev/isci/scil/sati_util.h>
67230557Sjimharris#include <dev/isci/scil/sati_move.h>
68230557Sjimharris
69230557Sjimharris#include <dev/isci/scil/intel_ata.h>
70230557Sjimharris#include <dev/isci/scil/intel_scsi.h>
71230557Sjimharris#include <dev/isci/scil/intel_sat.h>
72230557Sjimharris
73230557Sjimharris//******************************************************************************
74230557Sjimharris//* P R I V A T E   M E T H O D S
75230557Sjimharris//******************************************************************************
76230557Sjimharris
77230557Sjimharris/**
78230557Sjimharris * @brief This method performs the SCSI VERIFY command translation
79230557Sjimharris *        functionality common to all VERIFY command sizes.
80230557Sjimharris *        This includes:
81230557Sjimharris *        - setting the command register
82230557Sjimharris *        - setting the device head register
83230557Sjimharris *        - filling in fields in the SATI_TRANSLATOR_SEQUENCE object.
84230557Sjimharris *        For more information on the parameters passed to this method,
85230557Sjimharris *        please reference sati_translate_command().
86230557Sjimharris *
87230557Sjimharris * @return Indicate if the method was successfully completed.
88230557Sjimharris * @retval SATI_SUCCESS This is returned in all other cases.
89230557Sjimharris */
90230557Sjimharrisstatic
91230557SjimharrisSATI_STATUS sati_verify_translate_command(
92230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
93230557Sjimharris   void                       * scsi_io,
94230557Sjimharris   void                       * ata_io
95230557Sjimharris)
96230557Sjimharris{
97230557Sjimharris   U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
98230557Sjimharris   U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
99230557Sjimharris
100230557Sjimharris   /**
101230557Sjimharris    * The translator doesn't support performing the byte check operation.
102230557Sjimharris    * As a result, error the request if the BYTCHK bit is set.
103230557Sjimharris    */
104230557Sjimharris   if ((sati_get_cdb_byte(cdb, 1) & SCSI_VERIFY_BYTCHK_ENABLED))
105230557Sjimharris   {
106230557Sjimharris      sati_scsi_sense_data_construct(
107230557Sjimharris         sequence,
108230557Sjimharris         scsi_io,
109230557Sjimharris         SCSI_STATUS_CHECK_CONDITION,
110230557Sjimharris         SCSI_SENSE_ILLEGAL_REQUEST,
111230557Sjimharris         SCSI_ASC_INVALID_FIELD_IN_CDB,
112230557Sjimharris         SCSI_ASCQ_INVALID_FIELD_IN_CDB
113230557Sjimharris      );
114230557Sjimharris      return SATI_FAILURE_CHECK_RESPONSE_DATA;
115230557Sjimharris   }
116230557Sjimharris
117230557Sjimharris   sequence->protocol       = SAT_PROTOCOL_NON_DATA;
118230557Sjimharris   sequence->data_direction = SATI_DATA_DIRECTION_NONE;
119230557Sjimharris
120230557Sjimharris   sati_set_ata_device_head(register_fis, ATA_DEV_HEAD_REG_LBA_MODE_ENABLE);
121230557Sjimharris
122230557Sjimharris   // Ensure the device supports the 48 bit feature set.
123230557Sjimharris   if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE)
124230557Sjimharris      sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS_EXT);
125230557Sjimharris   else
126230557Sjimharris      sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS);
127230557Sjimharris
128230557Sjimharris   return SATI_SUCCESS;
129230557Sjimharris}
130230557Sjimharris
131230557Sjimharris//******************************************************************************
132230557Sjimharris//* P U B L I C   M E T H O D S
133230557Sjimharris//******************************************************************************
134230557Sjimharris
135230557Sjimharris/**
136230557Sjimharris * @brief This method performs all of the translation required for a
137230557Sjimharris *        SCSI VERIFY 10 byte CDB.
138230557Sjimharris *        This includes:
139230557Sjimharris *        - logical block address translation
140230557Sjimharris *        - transfer length (sector count) translation
141230557Sjimharris *        - translation items common to all VERIFY CDB sizes.
142230557Sjimharris *        For more information on the parameters passed to this method,
143230557Sjimharris *        please reference sati_translate_command().
144230557Sjimharris *
145230557Sjimharris * @return Indicate if the command translation was successful.
146230557Sjimharris *         For more information on return values please reference
147230557Sjimharris *         sati_move_set_sector_count(), sati_verify_translate_command()
148230557Sjimharris */
149230557SjimharrisSATI_STATUS sati_verify_10_translate_command(
150230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
151230557Sjimharris   void                       * scsi_io,
152230557Sjimharris   void                       * ata_io
153230557Sjimharris)
154230557Sjimharris{
155230557Sjimharris   SATI_STATUS   status;
156230557Sjimharris   U8          * cdb          = sati_cb_get_cdb_address(scsi_io);
157230557Sjimharris   U32           sector_count = (sati_get_cdb_byte(cdb, 7) << 8) |
158230557Sjimharris                                (sati_get_cdb_byte(cdb, 8));
159230557Sjimharris
160230557Sjimharris   if(sati_device_state_stopped(sequence, scsi_io))
161230557Sjimharris   {
162230557Sjimharris      return SATI_FAILURE_CHECK_RESPONSE_DATA;
163230557Sjimharris   }
164230557Sjimharris   else
165230557Sjimharris   {
166230557Sjimharris      sequence->type = SATI_SEQUENCE_VERIFY_10;
167230557Sjimharris
168230557Sjimharris      // Fill in the Logical Block Address fields and sector count registers.
169230557Sjimharris      sati_move_translate_32_bit_lba(sequence, scsi_io, ata_io);
170230557Sjimharris      status = sati_move_set_sector_count(sequence,scsi_io,ata_io,sector_count,0);
171230557Sjimharris      if (status != SATI_SUCCESS)
172230557Sjimharris         return status;
173230557Sjimharris
174230557Sjimharris      return sati_verify_translate_command(sequence, scsi_io, ata_io);
175230557Sjimharris   }
176230557Sjimharris}
177230557Sjimharris
178230557Sjimharris/**
179230557Sjimharris * @brief This method performs all of the translation required for a
180230557Sjimharris *        SCSI VERIFY 12 byte CDB.
181230557Sjimharris *        This includes:
182230557Sjimharris *        - logical block address translation
183230557Sjimharris *        - transfer length (sector count) translation
184230557Sjimharris *        - translation items common to all VERIFY CDB sizes.
185230557Sjimharris *        For more information on the parameters passed to this method,
186230557Sjimharris *        please reference sati_translate_command().
187230557Sjimharris *
188230557Sjimharris * @return Indicate if the command translation was successful.
189230557Sjimharris *         For more information on return values please reference
190230557Sjimharris *         sati_move_set_sector_count(), sati_verify_translate_command()
191230557Sjimharris */
192230557SjimharrisSATI_STATUS sati_verify_12_translate_command(
193230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
194230557Sjimharris   void                       * scsi_io,
195230557Sjimharris   void                       * ata_io
196230557Sjimharris)
197230557Sjimharris{
198230557Sjimharris   SATI_STATUS   status;
199230557Sjimharris   U8          * cdb          = sati_cb_get_cdb_address(scsi_io);
200230557Sjimharris   U32           sector_count = (sati_get_cdb_byte(cdb, 6) << 24) |
201230557Sjimharris                                (sati_get_cdb_byte(cdb, 7) << 16) |
202230557Sjimharris                                (sati_get_cdb_byte(cdb, 8) << 8)  |
203230557Sjimharris                                (sati_get_cdb_byte(cdb, 9));
204230557Sjimharris
205230557Sjimharris   if(sati_device_state_stopped(sequence, scsi_io))
206230557Sjimharris   {
207230557Sjimharris      return SATI_FAILURE_CHECK_RESPONSE_DATA;
208230557Sjimharris   }
209230557Sjimharris   else
210230557Sjimharris   {
211230557Sjimharris      sequence->type = SATI_SEQUENCE_VERIFY_12;
212230557Sjimharris
213230557Sjimharris      // Fill in the Logical Block Address fields and sector count registers.
214230557Sjimharris      sati_move_translate_32_bit_lba(sequence, scsi_io, ata_io);
215230557Sjimharris      status = sati_move_set_sector_count(sequence,scsi_io,ata_io,sector_count,0);
216230557Sjimharris      if (status != SATI_SUCCESS)
217230557Sjimharris         return status;
218230557Sjimharris
219230557Sjimharris      return sati_verify_translate_command(sequence, scsi_io, ata_io);
220230557Sjimharris   }
221230557Sjimharris}
222230557Sjimharris
223230557Sjimharris/**
224230557Sjimharris * @brief This method performs all of the translation required for a
225230557Sjimharris *        SCSI VERIFY 16 byte CDB.
226230557Sjimharris *        This includes:
227230557Sjimharris *        - logical block address translation
228230557Sjimharris *        - transfer length (sector count) translation
229230557Sjimharris *        - translation items common to all VERIFY CDB sizes.
230230557Sjimharris *        For more information on the parameters passed to this method,
231230557Sjimharris *        please reference sati_translate_command().
232230557Sjimharris *
233230557Sjimharris * @return Indicate if the command translation was successful.
234230557Sjimharris *         For more information on return values please reference
235230557Sjimharris *         sati_move_set_sector_count(), sati_verify_translate_command()
236230557Sjimharris */
237230557SjimharrisSATI_STATUS sati_verify_16_translate_command(
238230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
239230557Sjimharris   void                       * scsi_io,
240230557Sjimharris   void                       * ata_io
241230557Sjimharris)
242230557Sjimharris{
243230557Sjimharris   SATI_STATUS   status;
244230557Sjimharris   U8          * cdb          = sati_cb_get_cdb_address(scsi_io);
245230557Sjimharris   U32           sector_count = (sati_get_cdb_byte(cdb, 10) << 24) |
246230557Sjimharris                                (sati_get_cdb_byte(cdb, 11) << 16) |
247230557Sjimharris                                (sati_get_cdb_byte(cdb, 12) << 8)  |
248230557Sjimharris                                (sati_get_cdb_byte(cdb, 13));
249230557Sjimharris
250230557Sjimharris   if(sati_device_state_stopped(sequence, scsi_io))
251230557Sjimharris   {
252230557Sjimharris      return SATI_FAILURE_CHECK_RESPONSE_DATA;
253230557Sjimharris   }
254230557Sjimharris   else
255230557Sjimharris   {
256230557Sjimharris      sequence->type = SATI_SEQUENCE_VERIFY_16;
257230557Sjimharris
258230557Sjimharris      // Fill in the Logical Block Address field.
259230557Sjimharris      status = sati_move_translate_64_bit_lba(sequence, scsi_io, ata_io);
260230557Sjimharris      if (status != SATI_SUCCESS)
261230557Sjimharris         return status;
262230557Sjimharris
263230557Sjimharris      // Fill in the Sector Count fields.
264230557Sjimharris      status = sati_move_set_sector_count(sequence,scsi_io,ata_io,sector_count,0);
265230557Sjimharris      if (status != SATI_SUCCESS)
266230557Sjimharris         return status;
267230557Sjimharris
268230557Sjimharris      return sati_verify_translate_command(sequence, scsi_io, ata_io);
269230557Sjimharris   }
270230557Sjimharris}
271230557Sjimharris
272230557Sjimharris#endif // !defined(DISABLE_SATI_VERIFY)
273230557Sjimharris
274