xref: /freebsd/sys/dev/isci/scil/sati_util.c (revision 3db51fb1720efdddd6e8c2045397f59a398692d3)
1f11c7f63SJim Harris /*-
2718cf2ccSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3718cf2ccSPedro F. Giffuni  *
4f11c7f63SJim Harris  * This file is provided under a dual BSD/GPLv2 license.  When using or
5f11c7f63SJim Harris  * redistributing this file, you may do so under either license.
6f11c7f63SJim Harris  *
7f11c7f63SJim Harris  * GPL LICENSE SUMMARY
8f11c7f63SJim Harris  *
9f11c7f63SJim Harris  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
10f11c7f63SJim Harris  *
11f11c7f63SJim Harris  * This program is free software; you can redistribute it and/or modify
12f11c7f63SJim Harris  * it under the terms of version 2 of the GNU General Public License as
13f11c7f63SJim Harris  * published by the Free Software Foundation.
14f11c7f63SJim Harris  *
15f11c7f63SJim Harris  * This program is distributed in the hope that it will be useful, but
16f11c7f63SJim Harris  * WITHOUT ANY WARRANTY; without even the implied warranty of
17f11c7f63SJim Harris  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18f11c7f63SJim Harris  * General Public License for more details.
19f11c7f63SJim Harris  *
20f11c7f63SJim Harris  * You should have received a copy of the GNU General Public License
21f11c7f63SJim Harris  * along with this program; if not, write to the Free Software
22f11c7f63SJim Harris  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23f11c7f63SJim Harris  * The full GNU General Public License is included in this distribution
24f11c7f63SJim Harris  * in the file called LICENSE.GPL.
25f11c7f63SJim Harris  *
26f11c7f63SJim Harris  * BSD LICENSE
27f11c7f63SJim Harris  *
28f11c7f63SJim Harris  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29f11c7f63SJim Harris  * All rights reserved.
30f11c7f63SJim Harris  *
31f11c7f63SJim Harris  * Redistribution and use in source and binary forms, with or without
32f11c7f63SJim Harris  * modification, are permitted provided that the following conditions
33f11c7f63SJim Harris  * are met:
34f11c7f63SJim Harris  *
35f11c7f63SJim Harris  *   * Redistributions of source code must retain the above copyright
36f11c7f63SJim Harris  *     notice, this list of conditions and the following disclaimer.
37f11c7f63SJim Harris  *   * Redistributions in binary form must reproduce the above copyright
38f11c7f63SJim Harris  *     notice, this list of conditions and the following disclaimer in
39f11c7f63SJim Harris  *     the documentation and/or other materials provided with the
40f11c7f63SJim Harris  *     distribution.
41f11c7f63SJim Harris  *
42f11c7f63SJim Harris  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43f11c7f63SJim Harris  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44f11c7f63SJim Harris  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45f11c7f63SJim Harris  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46f11c7f63SJim Harris  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47f11c7f63SJim Harris  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48f11c7f63SJim Harris  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49f11c7f63SJim Harris  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50f11c7f63SJim Harris  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51f11c7f63SJim Harris  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52f11c7f63SJim Harris  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53f11c7f63SJim Harris  */
54f11c7f63SJim Harris 
55f11c7f63SJim Harris #include <sys/cdefs.h>
56f11c7f63SJim Harris /**
57f11c7f63SJim Harris  * @file
58f11c7f63SJim Harris  * @brief This file contains all of the method implementations that
59f11c7f63SJim Harris  *        provide generic support for SATI.  Some methods can be utilized
60f11c7f63SJim Harris  *        by a user to construct ATA/ATAPI commands, copy ATA device
61f11c7f63SJim Harris  *        structure data, fill in sense data, etc.
62f11c7f63SJim Harris  */
63f11c7f63SJim Harris 
64f11c7f63SJim Harris #include <dev/isci/scil/sati_util.h>
65f11c7f63SJim Harris #include <dev/isci/scil/sati_callbacks.h>
66f11c7f63SJim Harris #include <dev/isci/scil/intel_scsi.h>
67f11c7f63SJim Harris #include <dev/isci/scil/intel_ata.h>
68f11c7f63SJim Harris #include <dev/isci/scil/intel_sat.h>
69f11c7f63SJim Harris #include <dev/isci/scil/intel_sas.h>
70f11c7f63SJim Harris 
71f11c7f63SJim Harris /**
72f11c7f63SJim Harris  * @brief This method will set the data direction, protocol, and transfer
73*3db51fb1SGordon Bergling  *        length for an ATA non-data command.
74f11c7f63SJim Harris  *
75f11c7f63SJim Harris  * @pre It is expected that the user will use this method for setting these
76f11c7f63SJim Harris  *      values in a non-data ATA command constuct.
77f11c7f63SJim Harris  *
78f11c7f63SJim Harris  * @param[out] ata_io This parameter specifies the ATA IO request structure
79f11c7f63SJim Harris  *             for which to build the IDENTIFY DEVICE command.
80f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
81f11c7f63SJim Harris  *             for which the command is being constructed.
82f11c7f63SJim Harris  *
83f11c7f63SJim Harris  * @return none.
84f11c7f63SJim Harris  */
sati_ata_non_data_command(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)85f11c7f63SJim Harris void sati_ata_non_data_command(
86f11c7f63SJim Harris    void                        * ata_io,
87f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T  * sequence
88f11c7f63SJim Harris )
89f11c7f63SJim Harris {
90f11c7f63SJim Harris    sequence->data_direction      = SATI_DATA_DIRECTION_NONE;
91f11c7f63SJim Harris    sequence->protocol            = SAT_PROTOCOL_NON_DATA;
92f11c7f63SJim Harris    sequence->ata_transfer_length = 0;
93f11c7f63SJim Harris }
94f11c7f63SJim Harris 
95f11c7f63SJim Harris /**
96f11c7f63SJim Harris  * @brief This method will construct the ATA identify device command.
97f11c7f63SJim Harris  *
98f11c7f63SJim Harris  * @pre It is expected that the user has properly set the current contents
99f11c7f63SJim Harris  *      of the register FIS to 0.
100f11c7f63SJim Harris  *
101f11c7f63SJim Harris  * @param[out] ata_io This parameter specifies the ATA IO request structure
102f11c7f63SJim Harris  *             for which to build the IDENTIFY DEVICE command.
103f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
104f11c7f63SJim Harris  *             for which the command is being constructed.
105f11c7f63SJim Harris  *
106f11c7f63SJim Harris  * @return none.
107f11c7f63SJim Harris  */
sati_ata_identify_device_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)108f11c7f63SJim Harris void sati_ata_identify_device_construct(
109f11c7f63SJim Harris    void                       * ata_io,
110f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
111f11c7f63SJim Harris )
112f11c7f63SJim Harris {
113f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
114f11c7f63SJim Harris 
115f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_IDENTIFY_DEVICE);
116f11c7f63SJim Harris    sequence->data_direction      = SATI_DATA_DIRECTION_IN;
117f11c7f63SJim Harris    sequence->protocol            = SAT_PROTOCOL_PIO_DATA_IN;
118f11c7f63SJim Harris    sequence->ata_transfer_length = sizeof(ATA_IDENTIFY_DEVICE_DATA_T);
119f11c7f63SJim Harris }
120f11c7f63SJim Harris 
121f11c7f63SJim Harris /**
122f11c7f63SJim Harris * @brief This method will construct the ATA Execute Device Diagnostic command.
123f11c7f63SJim Harris *
124f11c7f63SJim Harris * @param[out] ata_io This parameter specifies the ATA IO request structure
125f11c7f63SJim Harris *             for which to build the IDENTIFY DEVICE command.
126f11c7f63SJim Harris * @param[in]  sequence This parameter specifies the translator sequence
127f11c7f63SJim Harris *             for which the command is being constructed.
128f11c7f63SJim Harris *
129f11c7f63SJim Harris * @return none.
130f11c7f63SJim Harris */
sati_ata_execute_device_diagnostic_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)131f11c7f63SJim Harris void sati_ata_execute_device_diagnostic_construct(
132f11c7f63SJim Harris    void                       * ata_io,
133f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
134f11c7f63SJim Harris )
135f11c7f63SJim Harris {
136f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
137f11c7f63SJim Harris 
138f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_EXECUTE_DEVICE_DIAG);
139f11c7f63SJim Harris 
140f11c7f63SJim Harris    sequence->data_direction = SATI_DATA_DIRECTION_IN;
141f11c7f63SJim Harris    sequence->protocol = SAT_PROTOCOL_DEVICE_DIAGNOSTIC;
142f11c7f63SJim Harris    sequence->ata_transfer_length = 16;
143f11c7f63SJim Harris }
144f11c7f63SJim Harris 
145f11c7f63SJim Harris /**
146f11c7f63SJim Harris  * @brief This method will set data bytes in the user data area.  If the
147f11c7f63SJim Harris  *        caller requests it, the data written will be forced to ascii
148f11c7f63SJim Harris  *        printable characters if it isn't already a printable character.
149f11c7f63SJim Harris  *        A printable character is considered to be >= 0x20 and <= 0x70.
150f11c7f63SJim Harris  *
151f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translation sequence
152f11c7f63SJim Harris  *             for which to copy and swap the data.
153f11c7f63SJim Harris  * @param[out] destination_scsi_io This parameter specifies the SCSI IO
154f11c7f63SJim Harris  *             request containing the destination buffer into which to copy.
155f11c7f63SJim Harris  * @param[in]  destination_offset This parameter specifies the offset into
156f11c7f63SJim Harris  *             the data buffer where the information will be copied to.
157f11c7f63SJim Harris  * @param[in]  source_value This parameter specifies the value retrieved
158f11c7f63SJim Harris  *             from the source buffer that is to be copied into the user
159f11c7f63SJim Harris  *             buffer area.
160f11c7f63SJim Harris  * @param[in]  use_printable_chars This parameter indicates if the copy should
161f11c7f63SJim Harris  *             ensure that the value copied is considered an ASCII printable
162f11c7f63SJim Harris  *             character (e.g. A, B, " ", etc.).  These characters reside
163f11c7f63SJim Harris  *             in the 0x20 - 0x7E ASCII range.
164f11c7f63SJim Harris  *
165f11c7f63SJim Harris  * @return none
166f11c7f63SJim Harris  */
167f11c7f63SJim Harris static
sati_set_ascii_data_byte(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * destination_scsi_io,U32 destination_offset,U8 source_value,BOOL use_printable_chars)168f11c7f63SJim Harris void sati_set_ascii_data_byte(
169f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
170f11c7f63SJim Harris    void                       * destination_scsi_io,
171f11c7f63SJim Harris    U32                          destination_offset,
172f11c7f63SJim Harris    U8                           source_value,
173f11c7f63SJim Harris    BOOL                         use_printable_chars
174f11c7f63SJim Harris )
175f11c7f63SJim Harris {
176f11c7f63SJim Harris    // if the user requests that the copied data be ascii printable, then
177f11c7f63SJim Harris    // default to " " (i.e. 0x20) for all non-ascii printable characters.
178f11c7f63SJim Harris    if((use_printable_chars == TRUE)
179f11c7f63SJim Harris      && ((source_value < 0x20) || (source_value > 0x7E)))
180f11c7f63SJim Harris    {
181f11c7f63SJim Harris       source_value = 0x20;
182f11c7f63SJim Harris    }
183f11c7f63SJim Harris 
184f11c7f63SJim Harris    sati_set_data_byte(
185f11c7f63SJim Harris       sequence, destination_scsi_io, destination_offset, source_value
186f11c7f63SJim Harris    );
187f11c7f63SJim Harris }
188f11c7f63SJim Harris 
189f11c7f63SJim Harris /**
190f11c7f63SJim Harris  * @brief This method performs a copy operation using an offset into the
191f11c7f63SJim Harris  *        source buffer, an offset into the destination buffer, and a length.
192f11c7f63SJim Harris  *        It will perform the byte swap from the 16-bit identify field
193f11c7f63SJim Harris  *        into the network byte order SCSI location.
194f11c7f63SJim Harris  *
195f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translation sequence
196f11c7f63SJim Harris  *             for which to copy and swap the data.
197f11c7f63SJim Harris  * @param[out] destination_scsi_io This parameter specifies the SCSI IO
198f11c7f63SJim Harris  *             request containing the destination buffer into which to copy.
199f11c7f63SJim Harris  * @param[in]  destination_offset This parameter specifies the offset into
200f11c7f63SJim Harris  *             the data buffer where the information will be copied to.
201f11c7f63SJim Harris  * @param[in]  source_buffer This parameter specifies the source buffer from
202f11c7f63SJim Harris  *             which the data will be copied.
203f11c7f63SJim Harris  * @param[in]  source_offset This parameter specifies the offset into the
204f11c7f63SJim Harris  *             source buffer where the copy shall begin.
205f11c7f63SJim Harris  * @param[in]  length This parameter specifies the number of bytes to copy
206f11c7f63SJim Harris  *             during this operation.
207f11c7f63SJim Harris  * @param[in]  use_printable_chars This parameter indicates if the copy should
208f11c7f63SJim Harris  *             ensure that the value copied is considered an ASCII printable
209f11c7f63SJim Harris  *             character (e.g. A, B, " ", etc.).  These characters reside
210f11c7f63SJim Harris  *             in the 0x20 - 0x7E ASCII range.
211f11c7f63SJim Harris  *
212f11c7f63SJim Harris  * @return none
213f11c7f63SJim Harris  */
sati_ata_identify_device_copy_data(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * destination_scsi_io,U32 destination_offset,U8 * source_buffer,U32 source_offset,U32 length,BOOL use_printable_chars)214f11c7f63SJim Harris void sati_ata_identify_device_copy_data(
215f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
216f11c7f63SJim Harris    void                       * destination_scsi_io,
217f11c7f63SJim Harris    U32                          destination_offset,
218f11c7f63SJim Harris    U8                         * source_buffer,
219f11c7f63SJim Harris    U32                          source_offset,
220f11c7f63SJim Harris    U32                          length,
221f11c7f63SJim Harris    BOOL                         use_printable_chars
222f11c7f63SJim Harris )
223f11c7f63SJim Harris {
224f11c7f63SJim Harris    source_buffer += source_offset;
225f11c7f63SJim Harris    while (length > 0)
226f11c7f63SJim Harris    {
227f11c7f63SJim Harris       sati_set_ascii_data_byte(
228f11c7f63SJim Harris          sequence,
229f11c7f63SJim Harris          destination_scsi_io,
230f11c7f63SJim Harris          destination_offset,
231f11c7f63SJim Harris          *(source_buffer+1),
232f11c7f63SJim Harris          use_printable_chars
233f11c7f63SJim Harris       );
234f11c7f63SJim Harris 
235f11c7f63SJim Harris       sati_set_ascii_data_byte(
236f11c7f63SJim Harris          sequence,
237f11c7f63SJim Harris          destination_scsi_io,
238f11c7f63SJim Harris          destination_offset+1,
239f11c7f63SJim Harris          *source_buffer,
240f11c7f63SJim Harris          use_printable_chars
241f11c7f63SJim Harris       );
242f11c7f63SJim Harris 
243f11c7f63SJim Harris       destination_offset += 2;
244f11c7f63SJim Harris       source_buffer      += 2;
245f11c7f63SJim Harris       length             -= 2;
246f11c7f63SJim Harris    }
247f11c7f63SJim Harris }
248f11c7f63SJim Harris 
249f11c7f63SJim Harris /**
250f11c7f63SJim Harris  * @brief This method performs a copy operation using a source buffer,
251f11c7f63SJim Harris  *        an offset into the destination buffer, and a length.
252f11c7f63SJim Harris  *
253f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translation sequence
254f11c7f63SJim Harris  *             for which to copy and swap the data.
255f11c7f63SJim Harris  * @param[out] destination_scsi_io This parameter specifies the SCSI IO
256f11c7f63SJim Harris  *             request containing the destination buffer into which to copy.
257f11c7f63SJim Harris  * @param[in]  destination_offset This parameter specifies the offset into
258f11c7f63SJim Harris  *             the data buffer where the information will be copied to.
259f11c7f63SJim Harris  * @param[in]  source_buffer This parameter specifies the source buffer from
260f11c7f63SJim Harris  *             which the data will be copied.
261f11c7f63SJim Harris  * @param[in]  length This parameter specifies the number of bytes to copy
262f11c7f63SJim Harris  *             during this operation.
263f11c7f63SJim Harris  *
264f11c7f63SJim Harris  * @return none
265f11c7f63SJim Harris  */
sati_copy_data(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * destination_scsi_io,U32 destination_offset,U8 * source_buffer,U32 length)266f11c7f63SJim Harris void sati_copy_data(
267f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
268f11c7f63SJim Harris    void                       * destination_scsi_io,
269f11c7f63SJim Harris    U32                          destination_offset,
270f11c7f63SJim Harris    U8                         * source_buffer,
271f11c7f63SJim Harris    U32                          length
272f11c7f63SJim Harris )
273f11c7f63SJim Harris {
274f11c7f63SJim Harris    while (length > 0)
275f11c7f63SJim Harris    {
276f11c7f63SJim Harris       sati_set_data_byte(
277f11c7f63SJim Harris          sequence, destination_scsi_io, destination_offset, *source_buffer
278f11c7f63SJim Harris       );
279f11c7f63SJim Harris 
280f11c7f63SJim Harris       destination_offset++;
281f11c7f63SJim Harris       source_buffer++;
282f11c7f63SJim Harris       length--;
283f11c7f63SJim Harris    }
284f11c7f63SJim Harris }
285f11c7f63SJim Harris 
286f11c7f63SJim Harris /**
287f11c7f63SJim Harris  * @brief This method extracts the Logical Block Address high and low 32-bit
288f11c7f63SJim Harris  *        values and the sector count 32-bit value from the ATA identify
289f11c7f63SJim Harris  *        device data.
290f11c7f63SJim Harris  *
291f11c7f63SJim Harris  * @param[in]  identify This parameter specifies the ATA_IDENTIFY_DEVICE_DATA
292f11c7f63SJim Harris  *             from which to extract the sector information.
293f11c7f63SJim Harris  * @param[out] lba_high This parameter specifies the upper 32 bits for the
294f11c7f63SJim Harris  *             number of logical block addresses for the device. The upper
295f11c7f63SJim Harris  *             16-bits should always be 0, since 48-bits of LBA is the most
296f11c7f63SJim Harris  *             supported by an ATA device.
297f11c7f63SJim Harris  * @param[out] lba_low This parameter specifies the lower 32 bits for the
298f11c7f63SJim Harris  *             number of logical block addresses for the device.
299f11c7f63SJim Harris  * @param[out] sector_size This parameter specifies the 32-bits of sector
300f11c7f63SJim Harris  *             size.  If the ATA device doesn't support reporting it's
301f11c7f63SJim Harris  *             sector size, then 512 bytes is utilized as the default value.
302f11c7f63SJim Harris  *
303f11c7f63SJim Harris  * @return none
304f11c7f63SJim Harris  */
sati_ata_identify_device_get_sector_info(ATA_IDENTIFY_DEVICE_DATA_T * identify,U32 * lba_high,U32 * lba_low,U32 * sector_size)305f11c7f63SJim Harris void sati_ata_identify_device_get_sector_info(
306f11c7f63SJim Harris    ATA_IDENTIFY_DEVICE_DATA_T * identify,
307f11c7f63SJim Harris    U32                        * lba_high,
308f11c7f63SJim Harris    U32                        * lba_low,
309f11c7f63SJim Harris    U32                        * sector_size
310f11c7f63SJim Harris )
311f11c7f63SJim Harris {
312f11c7f63SJim Harris    // Calculate the values to be returned
313f11c7f63SJim Harris    // Calculation will be different if the SATA device supports
314f11c7f63SJim Harris    // 48-bit addressing.  Bit 10 of Word 86 of ATA Identify
315f11c7f63SJim Harris    if (identify->command_set_enabled1
316f11c7f63SJim Harris        & ATA_IDENTIFY_COMMAND_SET_SUPPORTED1_48BIT_ENABLE)
317f11c7f63SJim Harris    {
318f11c7f63SJim Harris       // This drive supports 48-bit addressing
319f11c7f63SJim Harris 
320f11c7f63SJim Harris       *lba_high  = identify->max_48bit_lba[7] << 24;
321f11c7f63SJim Harris       *lba_high |= identify->max_48bit_lba[6] << 16;
322f11c7f63SJim Harris       *lba_high |= identify->max_48bit_lba[5] << 8;
323f11c7f63SJim Harris       *lba_high |= identify->max_48bit_lba[4];
324f11c7f63SJim Harris 
325f11c7f63SJim Harris       *lba_low  = identify->max_48bit_lba[3] << 24;
326f11c7f63SJim Harris       *lba_low |= identify->max_48bit_lba[2] << 16;
327f11c7f63SJim Harris       *lba_low |= identify->max_48bit_lba[1] << 8;
328f11c7f63SJim Harris       *lba_low |= identify->max_48bit_lba[0];
329f11c7f63SJim Harris    }
330f11c7f63SJim Harris    else
331f11c7f63SJim Harris    {
332f11c7f63SJim Harris       // This device doesn't support 48-bit addressing
333f11c7f63SJim Harris       // Pull out the largest LBA from words 60 and 61.
334f11c7f63SJim Harris       *lba_high  = 0;
335f11c7f63SJim Harris       *lba_low   = identify->total_num_sectors[3] << 24;
336f11c7f63SJim Harris       *lba_low  |= identify->total_num_sectors[2] << 16;
337f11c7f63SJim Harris       *lba_low  |= identify->total_num_sectors[1] << 8;
338f11c7f63SJim Harris       *lba_low  |= identify->total_num_sectors[0];
339f11c7f63SJim Harris    }
340f11c7f63SJim Harris 
341f11c7f63SJim Harris    // If the ATA device reports its sector size (bit 12 of Word 106),
342f11c7f63SJim Harris    // then use that instead.
343f11c7f63SJim Harris    if (identify->physical_logical_sector_info
344f11c7f63SJim Harris        & ATA_IDENTIFY_SECTOR_LARGER_THEN_512_ENABLE)
345f11c7f63SJim Harris    {
346f11c7f63SJim Harris       *sector_size  = identify->words_per_logical_sector[3] << 24;
347f11c7f63SJim Harris       *sector_size |= identify->words_per_logical_sector[2] << 16;
348f11c7f63SJim Harris       *sector_size |= identify->words_per_logical_sector[1] << 8;
349f11c7f63SJim Harris       *sector_size |= identify->words_per_logical_sector[0];
350f11c7f63SJim Harris    }
351f11c7f63SJim Harris    else
352f11c7f63SJim Harris    {
353f11c7f63SJim Harris       // Default the sector size to 512 bytes
354f11c7f63SJim Harris       *sector_size = 512;
355f11c7f63SJim Harris    }
356f11c7f63SJim Harris }
357f11c7f63SJim Harris 
358f11c7f63SJim Harris /**
359f11c7f63SJim Harris  * @brief This method will construct the ATA check power mode command.
360f11c7f63SJim Harris  *
361f11c7f63SJim Harris  * @pre It is expected that the user has properly set the current contents
362f11c7f63SJim Harris  *      of the register FIS to 0.
363f11c7f63SJim Harris  *
364f11c7f63SJim Harris  * @param[out] ata_io This parameter specifies the ATA IO request structure
365f11c7f63SJim Harris  *             for which to build the CHECK POWER MODE command.
366f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
367f11c7f63SJim Harris  *             for which the command is being constructed.
368f11c7f63SJim Harris  *
369f11c7f63SJim Harris  * @return none.
370f11c7f63SJim Harris  */
sati_ata_check_power_mode_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)371f11c7f63SJim Harris void sati_ata_check_power_mode_construct(
372f11c7f63SJim Harris    void                       * ata_io,
373f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
374f11c7f63SJim Harris )
375f11c7f63SJim Harris {
376f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
377f11c7f63SJim Harris 
378f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_CHECK_POWER_MODE);
379f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
380f11c7f63SJim Harris }
381f11c7f63SJim Harris 
382f11c7f63SJim Harris /**
383f11c7f63SJim Harris  * @brief This method is utilized to set a specific byte in the sense
384f11c7f63SJim Harris  *        data area.  It will ensure that the supplied byte offset
385f11c7f63SJim Harris  *        isn't larger then the length of the requested sense data.
386f11c7f63SJim Harris  *
387f11c7f63SJim Harris  * @param[in] scsi_io This parameter specifies the user SCSI IO request
388f11c7f63SJim Harris  *            for which to set the sense data byte.
389f11c7f63SJim Harris  * @param[in] byte_offset This parameter specifies the byte offset into
390f11c7f63SJim Harris  *            the sense data buffer where the data should be written.
391f11c7f63SJim Harris  * @param[in] value This parameter specifies the 8-bit value to be written
392f11c7f63SJim Harris  *            into the sense data area.
393f11c7f63SJim Harris  *
394f11c7f63SJim Harris  * @return none
395f11c7f63SJim Harris  */
sati_set_sense_data_byte(U8 * sense_data,U32 max_sense_data_len,U32 byte_offset,U8 value)396f11c7f63SJim Harris void sati_set_sense_data_byte(
397f11c7f63SJim Harris    U8  * sense_data,
398f11c7f63SJim Harris    U32   max_sense_data_len,
399f11c7f63SJim Harris    U32   byte_offset,
400f11c7f63SJim Harris    U8    value
401f11c7f63SJim Harris )
402f11c7f63SJim Harris {
403f11c7f63SJim Harris    // Ensure that we don't attempt to write past the end of the sense
404f11c7f63SJim Harris    // data buffer.
405f11c7f63SJim Harris    if (byte_offset < max_sense_data_len)
406f11c7f63SJim Harris       sense_data[byte_offset] = value;
407f11c7f63SJim Harris }
408f11c7f63SJim Harris 
409f11c7f63SJim Harris /**
410f11c7f63SJim Harris  * @brief This method will construct the common response IU in the user
411f11c7f63SJim Harris  *           request's response IU location.
412f11c7f63SJim Harris  *
413f11c7f63SJim Harris  * @param[out] rsp_iu This parameter specifies the user request's
414f11c7f63SJim Harris  *                response IU to be constructed.
415f11c7f63SJim Harris  * @param[in]  scsi_status This parameter specifies the SCSI status
416f11c7f63SJim Harris  *                value for the user's IO request.
417f11c7f63SJim Harris  * @param[in]  sense_data_length This parameter specifies the sense data
418f11c7f63SJim Harris  *                length for response IU.
419f11c7f63SJim Harris  * @param[in]  data_present The parameter specifies the specific
420f11c7f63SJim Harris  *                data present value for response IU.
421f11c7f63SJim Harris  *
422f11c7f63SJim Harris  * @return none
423f11c7f63SJim Harris  */
sati_scsi_common_response_iu_construct(SCI_SSP_RESPONSE_IU_T * rsp_iu,U8 scsi_status,U8 sense_data_length,U8 data_present)424f11c7f63SJim Harris void sati_scsi_common_response_iu_construct(
425f11c7f63SJim Harris    SCI_SSP_RESPONSE_IU_T * rsp_iu,
426f11c7f63SJim Harris    U8                      scsi_status,
427f11c7f63SJim Harris    U8                      sense_data_length,
428f11c7f63SJim Harris    U8                      data_present
429f11c7f63SJim Harris )
430f11c7f63SJim Harris {
431f11c7f63SJim Harris    rsp_iu->sense_data_length[3] = sense_data_length;
432f11c7f63SJim Harris    rsp_iu->sense_data_length[2] = 0;
433f11c7f63SJim Harris    rsp_iu->sense_data_length[1] = 0;
434f11c7f63SJim Harris    rsp_iu->sense_data_length[0] = 0;
435f11c7f63SJim Harris    rsp_iu->status               = scsi_status;
436f11c7f63SJim Harris    rsp_iu->data_present         = data_present;
437f11c7f63SJim Harris }
438f11c7f63SJim Harris 
439f11c7f63SJim Harris /**
440f11c7f63SJim Harris  * @brief This method will construct the buffer for sense data
441f11c7f63SJim Harris  *        sense data buffer location.  Additionally, it will set the user's
442f11c7f63SJim Harris  *        SCSI status.
443f11c7f63SJim Harris  *
444f11c7f63SJim Harris  * @param[in,out] scsi_io This parameter specifies the user's IO request
445f11c7f63SJim Harris  *                for which to construct the buffer for sense data.
446f11c7f63SJim Harris  * @param[in]     scsi_status This parameter specifies the SCSI status
447f11c7f63SJim Harris  *                value for the user's IO request.
4480702f4f0SGordon Bergling  * @param[out]    sense_data This parameter
449f11c7f63SJim Harris  *
450f11c7f63SJim Harris  * @return none
451f11c7f63SJim Harris  */
452f11c7f63SJim Harris static
sati_scsi_get_sense_data_buffer(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,U8 scsi_status,U8 ** sense_data,U32 * sense_len)453f11c7f63SJim Harris void sati_scsi_get_sense_data_buffer(
454f11c7f63SJim Harris     SATI_TRANSLATOR_SEQUENCE_T      * sequence,
455f11c7f63SJim Harris     void                            * scsi_io,
456f11c7f63SJim Harris     U8                                scsi_status,
457f11c7f63SJim Harris     U8                             ** sense_data,
458f11c7f63SJim Harris     U32                             * sense_len)
459f11c7f63SJim Harris {
460f11c7f63SJim Harris #ifdef SATI_TRANSPORT_SUPPORTS_SAS
461f11c7f63SJim Harris    SCI_SSP_RESPONSE_IU_T * rsp_iu = (SCI_SSP_RESPONSE_IU_T*)
462f11c7f63SJim Harris                                     sati_cb_get_response_iu_address(scsi_io);
463f11c7f63SJim Harris 
464f11c7f63SJim Harris    sati_scsi_common_response_iu_construct(
465f11c7f63SJim Harris       rsp_iu,
466f11c7f63SJim Harris       scsi_status,
467f11c7f63SJim Harris       sati_scsi_get_sense_data_length(sequence, scsi_io),
468f11c7f63SJim Harris       SCSI_RESPONSE_DATA_PRES_SENSE_DATA
469f11c7f63SJim Harris    );
470f11c7f63SJim Harris 
471f11c7f63SJim Harris    *sense_data                   = (U8*) rsp_iu->data;
472f11c7f63SJim Harris    *sense_len                    = SSP_RESPONSE_IU_MAX_DATA * 4;  // dwords to bytes
473f11c7f63SJim Harris #else
474f11c7f63SJim Harris    *sense_data = sati_cb_get_sense_data_address(scsi_io);
475f11c7f63SJim Harris    *sense_len  = sati_cb_get_sense_data_length(scsi_io);
476f11c7f63SJim Harris    sati_cb_set_scsi_status(scsi_io, scsi_status);
477f11c7f63SJim Harris #endif // SATI_TRANSPORT_SUPPORTS_SAS
478f11c7f63SJim Harris }
479f11c7f63SJim Harris 
480f11c7f63SJim Harris /**
481f11c7f63SJim Harris  * @brief This method extract response code based on on device settings.
482f11c7f63SJim Harris  *
483f11c7f63SJim Harris  * @return response code
484f11c7f63SJim Harris  */
485f11c7f63SJim Harris static
sati_scsi_get_sense_data_response_code(SATI_TRANSLATOR_SEQUENCE_T * sequence)486f11c7f63SJim Harris U8 sati_scsi_get_sense_data_response_code(SATI_TRANSLATOR_SEQUENCE_T * sequence)
487f11c7f63SJim Harris {
488f11c7f63SJim Harris     if (sequence->device->descriptor_sense_enable)
489f11c7f63SJim Harris     {
490f11c7f63SJim Harris        return SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE;
491f11c7f63SJim Harris     }
492f11c7f63SJim Harris     else
493f11c7f63SJim Harris     {
494f11c7f63SJim Harris        return SCSI_FIXED_CURRENT_RESPONSE_CODE;
495f11c7f63SJim Harris     }
496f11c7f63SJim Harris }
497f11c7f63SJim Harris 
498f11c7f63SJim Harris /**
499f11c7f63SJim Harris  * @brief This method will return length of descriptor sense data for executed command.
500f11c7f63SJim Harris  *
501f11c7f63SJim Harris  * @return sense data length
502f11c7f63SJim Harris  */
503f11c7f63SJim Harris static
sati_scsi_get_descriptor_sense_data_length(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io)504f11c7f63SJim Harris U8 sati_scsi_get_descriptor_sense_data_length(SATI_TRANSLATOR_SEQUENCE_T * sequence,
505f11c7f63SJim Harris         void * scsi_io)
506f11c7f63SJim Harris {
507f11c7f63SJim Harris     U8 * cdb = sati_cb_get_cdb_address(scsi_io);
508f11c7f63SJim Harris     //Initial value is descriptor header length
509f11c7f63SJim Harris     U8 length = 8;
510f11c7f63SJim Harris 
511f11c7f63SJim Harris     switch (sati_get_cdb_byte(cdb, 0))
512f11c7f63SJim Harris     {
513f11c7f63SJim Harris #if !defined(DISABLE_SATI_WRITE_LONG)
514f11c7f63SJim Harris     case SCSI_WRITE_LONG_10:
515f11c7f63SJim Harris     case SCSI_WRITE_LONG_16:
516f11c7f63SJim Harris         length += SCSI_BLOCK_DESCRIPTOR_LENGTH +
517f11c7f63SJim Harris             SCSI_INFORMATION_DESCRIPTOR_LENGTH;
518f11c7f63SJim Harris         break;
519f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_WRITE_LONG)
520f11c7f63SJim Harris #if !defined(DISABLE_SATI_REASSIGN_BLOCKS)
521f11c7f63SJim Harris     case SCSI_REASSIGN_BLOCKS:
522f11c7f63SJim Harris         length += SCSI_CMD_SPECIFIC_DESCRIPTOR_LENGTH +
523f11c7f63SJim Harris             SCSI_INFORMATION_DESCRIPTOR_LENGTH;
524f11c7f63SJim Harris         break;
525f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
526f11c7f63SJim Harris     case SCSI_READ_6:
527f11c7f63SJim Harris     case SCSI_READ_10:
528f11c7f63SJim Harris     case SCSI_READ_12:
529f11c7f63SJim Harris     case SCSI_READ_16:
530f11c7f63SJim Harris     case SCSI_WRITE_6:
531f11c7f63SJim Harris     case SCSI_WRITE_10:
532f11c7f63SJim Harris     case SCSI_WRITE_12:
533f11c7f63SJim Harris     case SCSI_WRITE_16:
534f11c7f63SJim Harris #if !defined(DISABLE_SATI_VERIFY)
535f11c7f63SJim Harris     case SCSI_VERIFY_10:
536f11c7f63SJim Harris     case SCSI_VERIFY_12:
537f11c7f63SJim Harris     case SCSI_VERIFY_16:
538f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_VERIFY)
539f11c7f63SJim Harris #if    !defined(DISABLE_SATI_WRITE_AND_VERIFY)  \
540f11c7f63SJim Harris     && !defined(DISABLE_SATI_VERIFY)            \
541f11c7f63SJim Harris     && !defined(DISABLE_SATI_WRITE)
542f11c7f63SJim Harris 
543f11c7f63SJim Harris     case SCSI_WRITE_AND_VERIFY_10:
544f11c7f63SJim Harris     case SCSI_WRITE_AND_VERIFY_12:
545f11c7f63SJim Harris     case SCSI_WRITE_AND_VERIFY_16:
546f11c7f63SJim Harris #endif //    !defined(DISABLE_SATI_WRITE_AND_VERIFY)
547f11c7f63SJim Harris        // && !defined(DISABLE_SATI_VERIFY)
548f11c7f63SJim Harris        // && !defined(DISABLE_SATI_WRITE)
549f11c7f63SJim Harris         length += SCSI_INFORMATION_DESCRIPTOR_LENGTH;
550f11c7f63SJim Harris         break;
551f11c7f63SJim Harris     }
552f11c7f63SJim Harris 
553f11c7f63SJim Harris     return length;
554f11c7f63SJim Harris }
555f11c7f63SJim Harris 
556f11c7f63SJim Harris /**
557f11c7f63SJim Harris  * @brief This method will return length of sense data.
558f11c7f63SJim Harris  *
559f11c7f63SJim Harris  * @return sense data length
560f11c7f63SJim Harris  */
sati_scsi_get_sense_data_length(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io)561f11c7f63SJim Harris U8 sati_scsi_get_sense_data_length(SATI_TRANSLATOR_SEQUENCE_T * sequence, void * scsi_io)
562f11c7f63SJim Harris {
563f11c7f63SJim Harris     U8 response_code;
564f11c7f63SJim Harris 
565f11c7f63SJim Harris     response_code = sati_scsi_get_sense_data_response_code(sequence);
566f11c7f63SJim Harris 
567f11c7f63SJim Harris     switch (response_code)
568f11c7f63SJim Harris     {
569f11c7f63SJim Harris     case SCSI_FIXED_CURRENT_RESPONSE_CODE:
570f11c7f63SJim Harris     case SCSI_FIXED_DEFERRED_RESPONSE_CODE:
571f11c7f63SJim Harris         return SCSI_FIXED_SENSE_DATA_BASE_LENGTH;
572f11c7f63SJim Harris     break;
573f11c7f63SJim Harris     case SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE:
574f11c7f63SJim Harris     case SCSI_DESCRIPTOR_DEFERRED_RESPONSE_CODE:
575f11c7f63SJim Harris         return sati_scsi_get_descriptor_sense_data_length(sequence, scsi_io);
576f11c7f63SJim Harris     break;
577f11c7f63SJim Harris     }
578f11c7f63SJim Harris 
579f11c7f63SJim Harris     return SCSI_FIXED_SENSE_DATA_BASE_LENGTH;
580f11c7f63SJim Harris }
581f11c7f63SJim Harris 
582f11c7f63SJim Harris /**
583f11c7f63SJim Harris  * @brief This method will construct the sense data buffer in the user's
584f11c7f63SJim Harris  *        sense data buffer location.  Additionally, it will set the user's
585f11c7f63SJim Harris  *        SCSI status.
586f11c7f63SJim Harris  *
587f11c7f63SJim Harris  * @param[in]     sequence This parameter specifies the translation sequence
588f11c7f63SJim Harris  *                for which to construct the sense data.
589f11c7f63SJim Harris  * @param[in,out] scsi_io This parameter specifies the user's IO request
590f11c7f63SJim Harris  *                for which to construct the sense data.
591f11c7f63SJim Harris  * @param[in]     scsi_status This parameter specifies the SCSI status
592f11c7f63SJim Harris  *                value for the user's IO request.
593f11c7f63SJim Harris  * @param[in]     sense_key This parameter specifies the sense key to
594f11c7f63SJim Harris  *                be set for the user's IO request.
595f11c7f63SJim Harris  * @param[in]     additional_sense_code This parameter specifies the
596f11c7f63SJim Harris  *                additional sense code (ASC) key to be set for the user's
597f11c7f63SJim Harris  *                IO request.
598f11c7f63SJim Harris  * @param[in]     additional_sense_code_qualifier This parameter specifies
599f11c7f63SJim Harris  *                the additional sense code qualifier (ASCQ) key to be set
600f11c7f63SJim Harris  *                for the user's IO request.
601f11c7f63SJim Harris  *
602f11c7f63SJim Harris  * @return none
603f11c7f63SJim Harris  */
sati_scsi_sense_data_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,U8 scsi_status,U8 sense_key,U8 additional_sense_code,U8 additional_sense_code_qualifier)604f11c7f63SJim Harris void sati_scsi_sense_data_construct(
605f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
606f11c7f63SJim Harris    void                       * scsi_io,
607f11c7f63SJim Harris    U8                           scsi_status,
608f11c7f63SJim Harris    U8                           sense_key,
609f11c7f63SJim Harris    U8                           additional_sense_code,
610f11c7f63SJim Harris    U8                           additional_sense_code_qualifier
611f11c7f63SJim Harris )
612f11c7f63SJim Harris {
613f11c7f63SJim Harris     U8 response_code;
614f11c7f63SJim Harris 
615f11c7f63SJim Harris     response_code = sati_scsi_get_sense_data_response_code(sequence);
616f11c7f63SJim Harris 
617f11c7f63SJim Harris     switch (response_code)
618f11c7f63SJim Harris     {
619f11c7f63SJim Harris     case SCSI_FIXED_CURRENT_RESPONSE_CODE:
620f11c7f63SJim Harris     case SCSI_FIXED_DEFERRED_RESPONSE_CODE:
621f11c7f63SJim Harris     sati_scsi_fixed_sense_data_construct(sequence, scsi_io, scsi_status, response_code,
622f11c7f63SJim Harris                 sense_key, additional_sense_code, additional_sense_code_qualifier);
623f11c7f63SJim Harris     break;
624f11c7f63SJim Harris     case SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE:
625f11c7f63SJim Harris     case SCSI_DESCRIPTOR_DEFERRED_RESPONSE_CODE:
626f11c7f63SJim Harris         sati_scsi_descriptor_sense_data_construct(sequence, scsi_io, scsi_status, response_code,
627f11c7f63SJim Harris                 sense_key, additional_sense_code, additional_sense_code_qualifier);
628f11c7f63SJim Harris         break;
629f11c7f63SJim Harris     }
630f11c7f63SJim Harris 
631f11c7f63SJim Harris     sequence->is_sense_response_set = TRUE;
632f11c7f63SJim Harris }
633f11c7f63SJim Harris 
634f11c7f63SJim Harris /**
635f11c7f63SJim Harris  * @brief This method will construct the block descriptor in the user's descriptor
636f11c7f63SJim Harris  *            sense data buffer location.
637f11c7f63SJim Harris  *
638f11c7f63SJim Harris  * @param[in]     sense_data This parameter specifies the user SCSI IO request
639f11c7f63SJim Harris  *                for which to set the sense data byte.
640f11c7f63SJim Harris  * @param[in]     sense_len This parameter specifies length of the sense data
641f11c7f63SJim Harris  *                to be returned by SATI.
642f11c7f63SJim Harris  * @param[out]    descriptor_len This parameter returns the length of constructed
643f11c7f63SJim Harris  *                descriptor.
644f11c7f63SJim Harris  *
645f11c7f63SJim Harris  * @return none
646f11c7f63SJim Harris  */
647f11c7f63SJim Harris static
sati_scsi_block_descriptor_construct(U8 * sense_data,U32 sense_len)648f11c7f63SJim Harris void sati_scsi_block_descriptor_construct(
649f11c7f63SJim Harris         U8 * sense_data,
650f11c7f63SJim Harris         U32 sense_len)
651f11c7f63SJim Harris {
652f11c7f63SJim Harris     U8 ili = 1;
653f11c7f63SJim Harris 
654f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 0,  SCSI_BLOCK_DESCRIPTOR_TYPE);
655f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 1,  SCSI_BLOCK_DESCRIPTOR_ADDITIONAL_LENGTH);
656f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 2,  0);
657f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 3,  (ili << 5));
658f11c7f63SJim Harris }
659f11c7f63SJim Harris 
660f11c7f63SJim Harris /**
661f11c7f63SJim Harris  * @brief This method will construct the command-specific descriptor for
662f11c7f63SJim Harris  *           the descriptor sense data buffer in the user's sense data buffer
663f11c7f63SJim Harris  *           location.
664f11c7f63SJim Harris  *
665f11c7f63SJim Harris  * @param[in]     sense_data This parameter specifies the user SCSI IO request
666f11c7f63SJim Harris  *                for which to set the sense data byte.
667f11c7f63SJim Harris  * @param[in]     sense_len This parameter specifies length of the sense data
668f11c7f63SJim Harris  *                to be returned by SATI.
669f11c7f63SJim Harris  * @param[out]    descriptor_len This parameter returns the length of constructed
670f11c7f63SJim Harris  *                descriptor.
671f11c7f63SJim Harris  * @param[in]     information_buff This parameter specifies the address for which
672f11c7f63SJim Harris  *                to set the command-specific information buffer.
673f11c7f63SJim Harris  *
674f11c7f63SJim Harris  * @return none
675f11c7f63SJim Harris  */
676f11c7f63SJim Harris static
sati_scsi_command_specific_descriptor_construct(U8 * sense_data,U32 sense_len,U8 * information_buff)677f11c7f63SJim Harris void sati_scsi_command_specific_descriptor_construct(
678f11c7f63SJim Harris     U8       * sense_data,
679f11c7f63SJim Harris     U32        sense_len,
680f11c7f63SJim Harris     U8       * information_buff)
681f11c7f63SJim Harris {
682f11c7f63SJim Harris     U8 i;
683f11c7f63SJim Harris 
684f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 0,  SCSI_CMD_SPECIFIC_DESCRIPTOR_TYPE);
685f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 1,  SCSI_CMD_SPECIFIC_DESCRIPTOR_ADDITIONAL_LENGTH);
686f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 2,  0);
687f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 3,  0);
688f11c7f63SJim Harris 
689f11c7f63SJim Harris     // fill information buffer
690f11c7f63SJim Harris     // SBC 5.20.1 REASSIGN BLOCKS command overview
691f11c7f63SJim Harris     // If information about the first LBA not reassigned is not available
692f11c7f63SJim Harris     // COMMAND-SPECIFIC INFORMATION field shall be set to FFFF_FFFF_FFFF_FFFFh
693f11c7f63SJim Harris     for (i=0; i<8; i++)
694f11c7f63SJim Harris         sati_set_sense_data_byte(sense_data, sense_len, 4 + i, information_buff==NULL?0xFF:information_buff[i]);
695f11c7f63SJim Harris }
696f11c7f63SJim Harris 
697f11c7f63SJim Harris /**
698f11c7f63SJim Harris  * @brief This method will construct the information descriptor for
699f11c7f63SJim Harris  *           the descriptor sense data buffer in the user's sense data buffer
700f11c7f63SJim Harris  *           location.
701f11c7f63SJim Harris  *
702f11c7f63SJim Harris  * @param[in]     sense_data This parameter specifies the user SCSI IO request
703f11c7f63SJim Harris  *                for which to set the sense data byte.
704f11c7f63SJim Harris  * @param[in]     sense_len This parameter specifies length of the sense data
705f11c7f63SJim Harris  *                to be returned by SATI.
706f11c7f63SJim Harris  * @param[out]    descriptor_len This parameter returns the length of constructed
707f11c7f63SJim Harris  *                descriptor.
708f11c7f63SJim Harris  * @param[in]     information_buff This parameter specifies the address for which
709f11c7f63SJim Harris  *                to set the information buffer.
710f11c7f63SJim Harris  *
711f11c7f63SJim Harris  * @return none
712f11c7f63SJim Harris  */
713f11c7f63SJim Harris static
sati_scsi_information_descriptor_construct(U8 * sense_data,U32 sense_len,U8 * information_buff)714f11c7f63SJim Harris void sati_scsi_information_descriptor_construct(
715f11c7f63SJim Harris     U8      * sense_data,
716f11c7f63SJim Harris     U32       sense_len,
717f11c7f63SJim Harris     U8      * information_buff)
718f11c7f63SJim Harris {
719f11c7f63SJim Harris     U8 i;
720f11c7f63SJim Harris     U8 valid = 1;
721f11c7f63SJim Harris 
722f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 0,  SCSI_INFORMATION_DESCRIPTOR_TYPE);
723f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 1,  SCSI_INFORMATION_DESCRIPTOR_ADDITIONAL_LENGTH);
724f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 2,  (valid << 7));
725f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 3,  0);
726f11c7f63SJim Harris 
727f11c7f63SJim Harris     // fill information buffer
728f11c7f63SJim Harris     for (i=0; i<8; i++)
729f11c7f63SJim Harris         sati_set_sense_data_byte(sense_data, sense_len, 4 + i, information_buff==NULL?0:information_buff[i]);
730f11c7f63SJim Harris }
731f11c7f63SJim Harris 
732f11c7f63SJim Harris /**
733f11c7f63SJim Harris  * @brief This method will construct the descriptors in the user's descriptor
734f11c7f63SJim Harris  *           sense data buffer location.
735f11c7f63SJim Harris  *
736f11c7f63SJim Harris  * @param[in,out] scsi_io This parameter specifies the user's IO request
737f11c7f63SJim Harris  *                for which to construct the sense data.
738f11c7f63SJim Harris  * @param[in]     sense_data This parameter specifies the user SCSI IO request
739f11c7f63SJim Harris  *                for which to set the sense data byte.
740f11c7f63SJim Harris  * @param[in]     sense_len This parameter specifies length of the sense data
741f11c7f63SJim Harris  *                to be returned by SATI.
742f11c7f63SJim Harris  * @param[out]    descriptor_len This parameter returns the length of constructed
743f11c7f63SJim Harris  *                descriptor.
744f11c7f63SJim Harris  * @param[in]     information_buff This parameter specifies the address for which
745f11c7f63SJim Harris  *                to set the information buffer.
746f11c7f63SJim Harris  *
747f11c7f63SJim Harris  * @return none
748f11c7f63SJim Harris  */
749f11c7f63SJim Harris static
sati_scsi_common_descriptors_construct(void * scsi_io,U8 * sense_data,U32 sense_len,U8 * information_buff)750f11c7f63SJim Harris void sati_scsi_common_descriptors_construct(
751f11c7f63SJim Harris     void    * scsi_io,
752f11c7f63SJim Harris     U8      * sense_data,
753f11c7f63SJim Harris     U32       sense_len,
754f11c7f63SJim Harris     U8      * information_buff)
755f11c7f63SJim Harris {
756f11c7f63SJim Harris     U8 * cdb = sati_cb_get_cdb_address(scsi_io);
757f11c7f63SJim Harris     U8 offset = 0;
758f11c7f63SJim Harris 
759f11c7f63SJim Harris     switch (sati_get_cdb_byte(cdb, 0))
760f11c7f63SJim Harris     {
761f11c7f63SJim Harris #if !defined(DISABLE_SATI_WRITE_LONG)
762f11c7f63SJim Harris     case SCSI_WRITE_LONG_10:
763f11c7f63SJim Harris     case SCSI_WRITE_LONG_16:
764f11c7f63SJim Harris         sati_scsi_block_descriptor_construct(
765f11c7f63SJim Harris                 sense_data + offset,
766f11c7f63SJim Harris                 sense_len - offset);
767f11c7f63SJim Harris 
768f11c7f63SJim Harris         offset += SCSI_BLOCK_DESCRIPTOR_LENGTH;
769f11c7f63SJim Harris         sati_scsi_information_descriptor_construct(
770f11c7f63SJim Harris                   sense_data + offset,
771f11c7f63SJim Harris                   sense_len - offset,
772f11c7f63SJim Harris                   information_buff);
773f11c7f63SJim Harris 
774f11c7f63SJim Harris         offset += SCSI_INFORMATION_DESCRIPTOR_LENGTH;
775f11c7f63SJim Harris         break;
776f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_WRITE_LONG)
777f11c7f63SJim Harris #if !defined(DISABLE_SATI_REASSIGN_BLOCKS)
778f11c7f63SJim Harris     case SCSI_REASSIGN_BLOCKS:
779f11c7f63SJim Harris         sati_scsi_command_specific_descriptor_construct(
780f11c7f63SJim Harris           sense_data + offset,
781f11c7f63SJim Harris           sense_len - offset,
782f11c7f63SJim Harris           NULL);
783f11c7f63SJim Harris 
784f11c7f63SJim Harris         offset += SCSI_CMD_SPECIFIC_DESCRIPTOR_LENGTH;
785f11c7f63SJim Harris         sati_scsi_information_descriptor_construct(
786f11c7f63SJim Harris                   sense_data + offset,
787f11c7f63SJim Harris                   sense_len - offset,
788f11c7f63SJim Harris                   information_buff);
789f11c7f63SJim Harris 
790f11c7f63SJim Harris         offset += SCSI_INFORMATION_DESCRIPTOR_LENGTH;
791f11c7f63SJim Harris         break;
792f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
793f11c7f63SJim Harris     case SCSI_READ_6:
794f11c7f63SJim Harris     case SCSI_READ_10:
795f11c7f63SJim Harris     case SCSI_READ_12:
796f11c7f63SJim Harris     case SCSI_READ_16:
797f11c7f63SJim Harris     case SCSI_WRITE_6:
798f11c7f63SJim Harris     case SCSI_WRITE_10:
799f11c7f63SJim Harris     case SCSI_WRITE_12:
800f11c7f63SJim Harris     case SCSI_WRITE_16:
801f11c7f63SJim Harris #if !defined(DISABLE_SATI_VERIFY)
802f11c7f63SJim Harris     case SCSI_VERIFY_10:
803f11c7f63SJim Harris     case SCSI_VERIFY_12:
804f11c7f63SJim Harris     case SCSI_VERIFY_16:
805f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_VERIFY)
806f11c7f63SJim Harris #if    !defined(DISABLE_SATI_WRITE_AND_VERIFY)  \
807f11c7f63SJim Harris     && !defined(DISABLE_SATI_VERIFY)            \
808f11c7f63SJim Harris     && !defined(DISABLE_SATI_WRITE)
809f11c7f63SJim Harris 
810f11c7f63SJim Harris     case SCSI_WRITE_AND_VERIFY_10:
811f11c7f63SJim Harris     case SCSI_WRITE_AND_VERIFY_12:
812f11c7f63SJim Harris     case SCSI_WRITE_AND_VERIFY_16:
813f11c7f63SJim Harris #endif //    !defined(DISABLE_SATI_WRITE_AND_VERIFY)
814f11c7f63SJim Harris        // && !defined(DISABLE_SATI_VERIFY)
815f11c7f63SJim Harris        // && !defined(DISABLE_SATI_WRITE)
816f11c7f63SJim Harris         sati_scsi_information_descriptor_construct(
817f11c7f63SJim Harris                   sense_data + offset,
818f11c7f63SJim Harris                   sense_len - offset,
819f11c7f63SJim Harris                   information_buff);
820f11c7f63SJim Harris 
821f11c7f63SJim Harris         offset += SCSI_INFORMATION_DESCRIPTOR_LENGTH;
822f11c7f63SJim Harris         break;
823f11c7f63SJim Harris     }
824f11c7f63SJim Harris }
825f11c7f63SJim Harris 
826f11c7f63SJim Harris /**
827f11c7f63SJim Harris  * @brief This method will construct the descriptor sense data buffer in
828f11c7f63SJim Harris  *           the user's sense data buffer location.  Additionally, it will set
829f11c7f63SJim Harris  *           the user's SCSI status.
830f11c7f63SJim Harris  *
831f11c7f63SJim Harris  * @param[in]     sequence This parameter specifies the translation sequence
832f11c7f63SJim Harris  *                for which to construct the sense data.
833f11c7f63SJim Harris  * @param[in,out] scsi_io This parameter specifies the user's IO request
834f11c7f63SJim Harris  *                for which to construct the sense data.
835f11c7f63SJim Harris  * @param[in]     scsi_status This parameter specifies the SCSI status
836f11c7f63SJim Harris  *                value for the user's IO request.
837f11c7f63SJim Harris  * @param[in]     sense_key This parameter specifies the sense key to
838f11c7f63SJim Harris  *                be set for the user's IO request.
839f11c7f63SJim Harris  * @param[in]     additional_sense_code This parameter specifies the
840f11c7f63SJim Harris  *                additional sense code (ASC) key to be set for the user's
841f11c7f63SJim Harris  *                IO request.
842f11c7f63SJim Harris  * @param[in]     additional_sense_code_qualifier This parameter specifies
843f11c7f63SJim Harris  *                the additional sense code qualifier (ASCQ) key to be set
844f11c7f63SJim Harris  *                for the user's IO request.
845f11c7f63SJim Harris  *
846f11c7f63SJim Harris  * @return none
847f11c7f63SJim Harris  */
sati_scsi_descriptor_sense_data_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,U8 scsi_status,U8 response_code,U8 sense_key,U8 additional_sense_code,U8 additional_sense_code_qualifier)848f11c7f63SJim Harris void sati_scsi_descriptor_sense_data_construct(
849f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
850f11c7f63SJim Harris    void                       * scsi_io,
851f11c7f63SJim Harris    U8                           scsi_status,
852f11c7f63SJim Harris    U8                           response_code,
853f11c7f63SJim Harris    U8                           sense_key,
854f11c7f63SJim Harris    U8                           additional_sense_code,
855f11c7f63SJim Harris    U8                           additional_sense_code_qualifier
856f11c7f63SJim Harris )
857f11c7f63SJim Harris {
858f11c7f63SJim Harris    U8 * sense_data;
859f11c7f63SJim Harris    U32    sense_len;
860f11c7f63SJim Harris 
861f11c7f63SJim Harris    sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len);
862f11c7f63SJim Harris 
863f11c7f63SJim Harris    sati_set_sense_data_byte(
864f11c7f63SJim Harris       sense_data,
865f11c7f63SJim Harris       sense_len,
866f11c7f63SJim Harris       0,
867f11c7f63SJim Harris       response_code
868f11c7f63SJim Harris    );
869f11c7f63SJim Harris 
870f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 1,  sense_key);
871f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 2,  additional_sense_code);
872f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 3,  additional_sense_code_qualifier);
873f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 4,  0);
874f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 5,  0);
875f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 6,  0);
876f11c7f63SJim Harris 
877f11c7f63SJim Harris    sati_scsi_common_descriptors_construct(scsi_io, sense_data + 8, sense_len, NULL);
878f11c7f63SJim Harris 
879f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 7,  sati_scsi_get_descriptor_sense_data_length(sequence, scsi_io) - 8);
880f11c7f63SJim Harris }
881f11c7f63SJim Harris 
882f11c7f63SJim Harris /**
883f11c7f63SJim Harris  * @brief This method will construct the fixed format sense data buffer
884f11c7f63SJim Harris  *           in the user's sense data buffer location.  Additionally, it will
885f11c7f63SJim Harris  *          set the user's SCSI status.
886f11c7f63SJim Harris  *
887f11c7f63SJim Harris  * @param[in]     sequence This parameter specifies the translation sequence
888f11c7f63SJim Harris  *                for which to construct the sense data.
889f11c7f63SJim Harris  * @param[in,out] scsi_io This parameter specifies the user's IO request
890f11c7f63SJim Harris  *                for which to construct the sense data.
891f11c7f63SJim Harris  * @param[in]     scsi_status This parameter specifies the SCSI status
892f11c7f63SJim Harris  *                value for the user's IO request.
893f11c7f63SJim Harris  * @param[in]     sense_key This parameter specifies the sense key to
894f11c7f63SJim Harris  *                be set for the user's IO request.
895f11c7f63SJim Harris  * @param[in]     additional_sense_code This parameter specifies the
896f11c7f63SJim Harris  *                additional sense code (ASC) key to be set for the user's
897f11c7f63SJim Harris  *                IO request.
898f11c7f63SJim Harris  * @param[in]     additional_sense_code_qualifier This parameter specifies
899f11c7f63SJim Harris  *                the additional sense code qualifier (ASCQ) key to be set
900f11c7f63SJim Harris  *                for the user's IO request.
901f11c7f63SJim Harris  *
902f11c7f63SJim Harris  * @return none
903f11c7f63SJim Harris  */
sati_scsi_fixed_sense_data_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,U8 scsi_status,U8 response_code,U8 sense_key,U8 additional_sense_code,U8 additional_sense_code_qualifier)904f11c7f63SJim Harris void sati_scsi_fixed_sense_data_construct(
905f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
906f11c7f63SJim Harris    void                       * scsi_io,
907f11c7f63SJim Harris    U8                           scsi_status,
908f11c7f63SJim Harris    U8                           response_code,
909f11c7f63SJim Harris    U8                           sense_key,
910f11c7f63SJim Harris    U8                           additional_sense_code,
911f11c7f63SJim Harris    U8                           additional_sense_code_qualifier
912f11c7f63SJim Harris )
913f11c7f63SJim Harris {
914f11c7f63SJim Harris     U8 * sense_data;
915f11c7f63SJim Harris     U32  sense_len;
916f11c7f63SJim Harris 
917f11c7f63SJim Harris     sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len);
918f11c7f63SJim Harris 
919f11c7f63SJim Harris     // Write out the sense data format per SPC-4.
920f11c7f63SJim Harris     // We utilize the fixed format sense data format.
921f11c7f63SJim Harris 
922f11c7f63SJim Harris     sati_set_sense_data_byte(
923f11c7f63SJim Harris       sense_data,
924f11c7f63SJim Harris       sense_len,
925f11c7f63SJim Harris       0,
926f11c7f63SJim Harris       response_code | SCSI_FIXED_SENSE_DATA_VALID_BIT
927f11c7f63SJim Harris     );
928f11c7f63SJim Harris 
929f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 1,  0);
930f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 2,  sense_key);
931f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 3,  0);
932f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 4,  0);
933f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 5,  0);
934f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 6,  0);
9358a0ddeb8SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 7,  (sense_len < 18 ? sense_len - 1 : 17) - 7);
936f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 8,  0);
937f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 9,  0);
938f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 10, 0);
939f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 11, 0);
940f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 12, additional_sense_code);
941f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 13, additional_sense_code_qualifier);
942f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 14, 0);
943f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 15, 0);
944f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 16, 0);
945f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 17, 0);
946f11c7f63SJim Harris }
947f11c7f63SJim Harris 
948f11c7f63SJim Harris /**
949f11c7f63SJim Harris * @brief This method will construct common sense data that will be identical in
950f11c7f63SJim Harris *        both read error sense construct functions.
951f11c7f63SJim Harris *        sati_scsi_read_ncq_error_sense_construct,
952f11c7f63SJim Harris *        sati_scsi_read_error_sense_construct
953f11c7f63SJim Harris *
954f11c7f63SJim Harris  * @param[in]    sense_data This parameter specifies the user SCSI IO request
955f11c7f63SJim Harris  *               for which to set the sense data byte.
956f11c7f63SJim Harris * @param[in]     sense_len This parameter specifies length of the sense data
957f11c7f63SJim Harris *                to be returned by SATI.
958f11c7f63SJim Harris * @param[in]     sense_key This parameter specifies the sense key to
959f11c7f63SJim Harris *                be set for the user's IO request.
960f11c7f63SJim Harris * @param[in]     additional_sense_code This parameter specifies the
961f11c7f63SJim Harris *                additional sense code (ASC) key to be set for the user's
962f11c7f63SJim Harris *                IO request.
963f11c7f63SJim Harris * @param[in]     additional_sense_code_qualifier This parameter specifies
964f11c7f63SJim Harris *                the additional sense code qualifier (ASCQ) key to be set
965f11c7f63SJim Harris *                for the user's IO request.
966f11c7f63SJim Harris *
967f11c7f63SJim Harris * @return none
968f11c7f63SJim Harris */
969f11c7f63SJim Harris static
sati_scsi_common_fixed_sense_construct(U8 * sense_data,U32 sense_len,U8 sense_key,U8 additional_sense_code,U8 additional_sense_code_qualifier)970f11c7f63SJim Harris void sati_scsi_common_fixed_sense_construct(
971f11c7f63SJim Harris    U8                         * sense_data,
972f11c7f63SJim Harris    U32                          sense_len,
973f11c7f63SJim Harris    U8                           sense_key,
974f11c7f63SJim Harris    U8                           additional_sense_code,
975f11c7f63SJim Harris    U8                           additional_sense_code_qualifier
976f11c7f63SJim Harris )
977f11c7f63SJim Harris {
978f11c7f63SJim Harris 
979f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 1,  0);
980f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 2,  sense_key);
981f11c7f63SJim Harris 
982f11c7f63SJim Harris    //Bytes 3, 4, 5, 6 are set in read_error_sense_construct functions
983f11c7f63SJim Harris 
9848a0ddeb8SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 7,  (sense_len < 18 ? sense_len - 1 : 17) - 7);
985f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 8,  0);
986f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 9,  0);
987f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 10, 0);
988f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 11, 0);
989f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 12, additional_sense_code);
990f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 13, additional_sense_code_qualifier);
991f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 14, 0);
992f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 15, 0x80);
993f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 16, 0);
994f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 17, 0);
995f11c7f63SJim Harris }
996f11c7f63SJim Harris 
997f11c7f63SJim Harris /**
998f11c7f63SJim Harris  * @brief This method will construct the descriptor sense data buffer in
999f11c7f63SJim Harris  *           the user's sense data buffer location.  Additionally, it will set
1000f11c7f63SJim Harris  *           the user's SCSI status.
1001f11c7f63SJim Harris  *
1002f11c7f63SJim Harris  * @param[in]     sequence This parameter specifies the translation sequence
1003f11c7f63SJim Harris  *                for which to construct the sense data.
1004f11c7f63SJim Harris  * @param[in,out] scsi_io This parameter specifies the user's IO request
1005f11c7f63SJim Harris  *                for which to construct the sense data.
1006f11c7f63SJim Harris  * @param[in]     scsi_status This parameter specifies the SCSI status
1007f11c7f63SJim Harris  *                value for the user's IO request.
1008f11c7f63SJim Harris  * @param[in]     sense_key This parameter specifies the sense key to
1009f11c7f63SJim Harris  *                be set for the user's IO request.
1010f11c7f63SJim Harris  * @param[in]     additional_sense_code This parameter specifies the
1011f11c7f63SJim Harris  *                additional sense code (ASC) key to be set for the user's
1012f11c7f63SJim Harris  *                IO request.
1013f11c7f63SJim Harris  * @param[in]     additional_sense_code_qualifier This parameter specifies
1014f11c7f63SJim Harris  *                the additional sense code qualifier (ASCQ) key to be set
1015f11c7f63SJim Harris  *                for the user's IO request.
1016f11c7f63SJim Harris  *
1017f11c7f63SJim Harris  * @return none
1018f11c7f63SJim Harris  */
1019f11c7f63SJim Harris static
sati_scsi_common_descriptor_sense_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,U8 * sense_data,U32 sense_len,U8 sense_key,U8 additional_sense_code,U8 additional_sense_code_qualifier,U8 * information_buff)1020f11c7f63SJim Harris void sati_scsi_common_descriptor_sense_construct(
1021f11c7f63SJim Harris     SATI_TRANSLATOR_SEQUENCE_T * sequence,
1022f11c7f63SJim Harris     void                       * scsi_io,
1023f11c7f63SJim Harris     U8                         * sense_data,
1024f11c7f63SJim Harris     U32                          sense_len,
1025f11c7f63SJim Harris     U8                           sense_key,
1026f11c7f63SJim Harris     U8                           additional_sense_code,
1027f11c7f63SJim Harris     U8                           additional_sense_code_qualifier,
1028f11c7f63SJim Harris     U8                         * information_buff
1029f11c7f63SJim Harris )
1030f11c7f63SJim Harris {
1031f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 1,  sense_key);
1032f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 2,  additional_sense_code);
1033f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 3,  additional_sense_code_qualifier);
1034f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 4,  0);
1035f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 5,  0);
1036f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 6,  0);
1037f11c7f63SJim Harris 
1038f11c7f63SJim Harris     sati_scsi_common_descriptors_construct(scsi_io, sense_data + 8, sense_len, information_buff);
1039f11c7f63SJim Harris 
1040f11c7f63SJim Harris     sati_set_sense_data_byte(sense_data, sense_len, 7,  sati_scsi_get_descriptor_sense_data_length(sequence, scsi_io) - 8);
1041f11c7f63SJim Harris }
1042f11c7f63SJim Harris 
1043f11c7f63SJim Harris /**
1044f11c7f63SJim Harris * @brief This method will construct the sense data buffer in the user's
1045f11c7f63SJim Harris *        descriptor sense data buffer location.  Additionally, it will set
1046f11c7f63SJim Harris *        the user's SCSI status. This is only used for NCQ uncorrectable
1047f11c7f63SJim Harris *        read errors
1048f11c7f63SJim Harris *
1049f11c7f63SJim Harris * @param[in]     sequence This parameter specifies the translation sequence
1050f11c7f63SJim Harris *                for which to construct the sense data.
1051f11c7f63SJim Harris * @param[in,out] scsi_io This parameter specifies the user's IO request
1052f11c7f63SJim Harris *                for which to construct the sense data.
1053f11c7f63SJim Harris * @param[in]     ata_input_data This parameter specifies the user's ATA IO
1054f11c7f63SJim Harris *                response from a Read Log Ext command.
1055f11c7f63SJim Harris * @param[in]     scsi_status This parameter specifies the SCSI status
1056f11c7f63SJim Harris *                value for the user's IO request.
1057f11c7f63SJim Harris * @param[in]     sense_key This parameter specifies the sense key to
1058f11c7f63SJim Harris *                be set for the user's IO request.
1059f11c7f63SJim Harris * @param[in]     additional_sense_code This parameter specifies the
1060f11c7f63SJim Harris *                additional sense code (ASC) key to be set for the user's
1061f11c7f63SJim Harris *                IO request.
1062f11c7f63SJim Harris * @param[in]     additional_sense_code_qualifier This parameter specifies
1063f11c7f63SJim Harris *                the additional sense code qualifier (ASCQ) key to be set
1064f11c7f63SJim Harris *                for the user's IO request.
1065f11c7f63SJim Harris *
1066f11c7f63SJim Harris * @return none
1067f11c7f63SJim Harris */
1068f11c7f63SJim Harris static
sati_scsi_read_ncq_error_descriptor_sense_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_input_data,U8 scsi_status,U8 response_code,U8 sense_key,U8 additional_sense_code,U8 additional_sense_code_qualifier)1069f11c7f63SJim Harris void sati_scsi_read_ncq_error_descriptor_sense_construct(
1070f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1071f11c7f63SJim Harris    void                       * scsi_io,
1072f11c7f63SJim Harris    void                       * ata_input_data,
1073f11c7f63SJim Harris    U8                           scsi_status,
1074f11c7f63SJim Harris    U8                           response_code,
1075f11c7f63SJim Harris    U8                           sense_key,
1076f11c7f63SJim Harris    U8                           additional_sense_code,
1077f11c7f63SJim Harris    U8                           additional_sense_code_qualifier
1078f11c7f63SJim Harris )
1079f11c7f63SJim Harris {
1080f11c7f63SJim Harris    U8 * sense_data;
1081f11c7f63SJim Harris    U32  sense_len;
1082f11c7f63SJim Harris 
1083f11c7f63SJim Harris    U8 information_buff[8] = {0};
1084f11c7f63SJim Harris 
1085f11c7f63SJim Harris    ATA_NCQ_COMMAND_ERROR_LOG_T * ncq_log = (ATA_NCQ_COMMAND_ERROR_LOG_T *) ata_input_data;
1086f11c7f63SJim Harris 
1087f11c7f63SJim Harris    sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len);
1088f11c7f63SJim Harris 
1089f11c7f63SJim Harris    sati_set_sense_data_byte(
1090f11c7f63SJim Harris       sense_data,
1091f11c7f63SJim Harris       sense_len,
1092f11c7f63SJim Harris       0,
1093f11c7f63SJim Harris       response_code
1094f11c7f63SJim Harris    );
1095f11c7f63SJim Harris 
1096f11c7f63SJim Harris    information_buff[2] = ncq_log->lba_47_40;
1097f11c7f63SJim Harris    information_buff[3] = ncq_log->lba_39_32;
1098f11c7f63SJim Harris    information_buff[4] = ncq_log->lba_31_24;
1099f11c7f63SJim Harris    information_buff[5] = ncq_log->lba_23_16;
1100f11c7f63SJim Harris    information_buff[6] = ncq_log->lba_15_8;
1101f11c7f63SJim Harris    information_buff[7] = ncq_log->lba_7_0;
1102f11c7f63SJim Harris 
1103f11c7f63SJim Harris    sati_scsi_common_descriptor_sense_construct(
1104f11c7f63SJim Harris            sequence,
1105f11c7f63SJim Harris            scsi_io,
1106f11c7f63SJim Harris            sense_data,
1107f11c7f63SJim Harris            sense_len,
1108f11c7f63SJim Harris            sense_key,
1109f11c7f63SJim Harris            additional_sense_code,
1110f11c7f63SJim Harris            additional_sense_code_qualifier,
1111f11c7f63SJim Harris            information_buff
1112f11c7f63SJim Harris    );
1113f11c7f63SJim Harris }
1114f11c7f63SJim Harris 
1115f11c7f63SJim Harris /**
1116f11c7f63SJim Harris * @brief This method will construct the sense data buffer in the user's
1117f11c7f63SJim Harris *        sense data buffer location.  Additionally, it will set the user's
1118f11c7f63SJim Harris *        SCSI status. This is only used for NCQ uncorrectable read errors
1119f11c7f63SJim Harris *
1120f11c7f63SJim Harris * @param[in]     sequence This parameter specifies the translation sequence
1121f11c7f63SJim Harris *                for which to construct the sense data.
1122f11c7f63SJim Harris * @param[in,out] scsi_io This parameter specifies the user's IO request
1123f11c7f63SJim Harris *                for which to construct the sense data.
1124f11c7f63SJim Harris * @param[in]     ata_input_data This parameter specifies the user's ATA IO
1125f11c7f63SJim Harris *                response from a Read Log Ext command.
1126f11c7f63SJim Harris * @param[in]     scsi_status This parameter specifies the SCSI status
1127f11c7f63SJim Harris *                value for the user's IO request.
1128f11c7f63SJim Harris * @param[in]     sense_key This parameter specifies the sense key to
1129f11c7f63SJim Harris *                be set for the user's IO request.
1130f11c7f63SJim Harris * @param[in]     additional_sense_code This parameter specifies the
1131f11c7f63SJim Harris *                additional sense code (ASC) key to be set for the user's
1132f11c7f63SJim Harris *                IO request.
1133f11c7f63SJim Harris * @param[in]     additional_sense_code_qualifier This parameter specifies
1134f11c7f63SJim Harris *                the additional sense code qualifier (ASCQ) key to be set
1135f11c7f63SJim Harris *                for the user's IO request.
1136f11c7f63SJim Harris *
1137f11c7f63SJim Harris * @return none
1138f11c7f63SJim Harris */
1139f11c7f63SJim Harris static
sati_scsi_read_ncq_error_fixed_sense_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_input_data,U8 scsi_status,U8 response_code,U8 sense_key,U8 additional_sense_code,U8 additional_sense_code_qualifier)1140f11c7f63SJim Harris void sati_scsi_read_ncq_error_fixed_sense_construct(
1141f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1142f11c7f63SJim Harris    void                       * scsi_io,
1143f11c7f63SJim Harris    void                       * ata_input_data,
1144f11c7f63SJim Harris    U8                           scsi_status,
1145f11c7f63SJim Harris    U8                           response_code,
1146f11c7f63SJim Harris    U8                           sense_key,
1147f11c7f63SJim Harris    U8                           additional_sense_code,
1148f11c7f63SJim Harris    U8                           additional_sense_code_qualifier
1149f11c7f63SJim Harris )
1150f11c7f63SJim Harris {
1151f11c7f63SJim Harris    U8 * sense_data;
1152f11c7f63SJim Harris    U32  sense_len;
1153f11c7f63SJim Harris    U8   valid = TRUE;
1154f11c7f63SJim Harris 
1155f11c7f63SJim Harris    ATA_NCQ_COMMAND_ERROR_LOG_T * ncq_log = (ATA_NCQ_COMMAND_ERROR_LOG_T *) ata_input_data;
1156f11c7f63SJim Harris 
1157f11c7f63SJim Harris    sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len);
1158f11c7f63SJim Harris 
1159f11c7f63SJim Harris    if(ncq_log->lba_39_32 > 0)
1160f11c7f63SJim Harris    {
1161f11c7f63SJim Harris       valid = FALSE;
1162f11c7f63SJim Harris    }
1163f11c7f63SJim Harris 
1164f11c7f63SJim Harris    sati_set_sense_data_byte(
1165f11c7f63SJim Harris       sense_data,
1166f11c7f63SJim Harris       sense_len,
1167f11c7f63SJim Harris       0,
1168f11c7f63SJim Harris       (valid << 7) | response_code
1169f11c7f63SJim Harris    );
1170f11c7f63SJim Harris 
1171f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 3,  ncq_log->lba_31_24);
1172f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 4,  ncq_log->lba_23_16);
1173f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 5,  ncq_log->lba_15_8);
1174f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 6,  ncq_log->lba_7_0);
1175f11c7f63SJim Harris 
1176f11c7f63SJim Harris    sati_scsi_common_fixed_sense_construct(
1177f11c7f63SJim Harris       sense_data,
1178f11c7f63SJim Harris       sense_len,
1179f11c7f63SJim Harris       sense_key,
1180f11c7f63SJim Harris       additional_sense_code,
1181f11c7f63SJim Harris       additional_sense_code_qualifier
1182f11c7f63SJim Harris    );
1183f11c7f63SJim Harris }
1184f11c7f63SJim Harris 
sati_scsi_read_ncq_error_sense_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_input_data,U8 scsi_status,U8 sense_key,U8 additional_sense_code,U8 additional_sense_code_qualifier)1185f11c7f63SJim Harris void sati_scsi_read_ncq_error_sense_construct(
1186f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1187f11c7f63SJim Harris    void                       * scsi_io,
1188f11c7f63SJim Harris    void                       * ata_input_data,
1189f11c7f63SJim Harris    U8                           scsi_status,
1190f11c7f63SJim Harris    U8                           sense_key,
1191f11c7f63SJim Harris    U8                           additional_sense_code,
1192f11c7f63SJim Harris    U8                           additional_sense_code_qualifier
1193f11c7f63SJim Harris )
1194f11c7f63SJim Harris {
1195f11c7f63SJim Harris     U8 response_code;
1196f11c7f63SJim Harris 
1197f11c7f63SJim Harris     response_code = sati_scsi_get_sense_data_response_code(sequence);
1198f11c7f63SJim Harris 
1199f11c7f63SJim Harris     switch (response_code)
1200f11c7f63SJim Harris     {
1201f11c7f63SJim Harris     case SCSI_FIXED_CURRENT_RESPONSE_CODE:
1202f11c7f63SJim Harris     case SCSI_FIXED_DEFERRED_RESPONSE_CODE:
1203f11c7f63SJim Harris         sati_scsi_read_ncq_error_fixed_sense_construct(sequence, scsi_io, ata_input_data, scsi_status,
1204f11c7f63SJim Harris                 response_code, sense_key, additional_sense_code, additional_sense_code_qualifier);
1205f11c7f63SJim Harris     break;
1206f11c7f63SJim Harris     case SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE:
1207f11c7f63SJim Harris     case SCSI_DESCRIPTOR_DEFERRED_RESPONSE_CODE:
1208f11c7f63SJim Harris         sati_scsi_read_ncq_error_descriptor_sense_construct(sequence, scsi_io, ata_input_data, scsi_status,
1209f11c7f63SJim Harris                 response_code, sense_key, additional_sense_code, additional_sense_code_qualifier);
1210f11c7f63SJim Harris         break;
1211f11c7f63SJim Harris     }
1212f11c7f63SJim Harris 
1213f11c7f63SJim Harris     sequence->is_sense_response_set = TRUE;
1214f11c7f63SJim Harris }
1215f11c7f63SJim Harris 
1216f11c7f63SJim Harris /**
1217f11c7f63SJim Harris * @brief This method will construct the sense data buffer in the user's
1218f11c7f63SJim Harris *        sense data buffer location.  Additionally, it will set the user's
1219f11c7f63SJim Harris *        SCSI status. This is used for uncorrectable read errors.
1220f11c7f63SJim Harris *
1221f11c7f63SJim Harris * @param[in]     sequence This parameter specifies the translation sequence
1222f11c7f63SJim Harris *                for which to construct the sense data.
1223f11c7f63SJim Harris * @param[in,out] scsi_io This parameter specifies the user's IO request
1224f11c7f63SJim Harris *                for which to construct the sense data.
1225f11c7f63SJim Harris * @param[in]     ata_io This parameter is a pointer to the ATA IO data used
1226f11c7f63SJim Harris *                to get the ATA register fis.
1227f11c7f63SJim Harris * @param[in]     scsi_status This parameter specifies the SCSI status
1228f11c7f63SJim Harris *                value for the user's IO request.
1229f11c7f63SJim Harris * @param[in]     sense_key This parameter specifies the sense key to
1230f11c7f63SJim Harris *                be set for the user's IO request.
1231f11c7f63SJim Harris * @param[in]     additional_sense_code This parameter specifies the
1232f11c7f63SJim Harris *                additional sense code (ASC) key to be set for the user's
1233f11c7f63SJim Harris *                IO request.
1234f11c7f63SJim Harris * @param[in]     additional_sense_code_qualifier This parameter specifies
1235f11c7f63SJim Harris *                the additional sense code qualifier (ASCQ) key to be set
1236f11c7f63SJim Harris *                for the user's IO request.
1237f11c7f63SJim Harris *
1238f11c7f63SJim Harris * @return none
1239f11c7f63SJim Harris */
1240f11c7f63SJim Harris static
sati_scsi_read_error_descriptor_sense_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io,U8 scsi_status,U8 response_code,U8 sense_key,U8 additional_sense_code,U8 additional_sense_code_qualifier)1241f11c7f63SJim Harris void sati_scsi_read_error_descriptor_sense_construct(
1242f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1243f11c7f63SJim Harris    void                       * scsi_io,
1244f11c7f63SJim Harris    void                       * ata_io,
1245f11c7f63SJim Harris    U8                           scsi_status,
1246f11c7f63SJim Harris    U8                           response_code,
1247f11c7f63SJim Harris    U8                           sense_key,
1248f11c7f63SJim Harris    U8                           additional_sense_code,
1249f11c7f63SJim Harris    U8                           additional_sense_code_qualifier
1250f11c7f63SJim Harris )
1251f11c7f63SJim Harris {
1252f11c7f63SJim Harris    U8 * sense_data;
1253f11c7f63SJim Harris    U32  sense_len;
1254f11c7f63SJim Harris    U8 information_buff[8] = {0};
1255f11c7f63SJim Harris 
1256f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
1257f11c7f63SJim Harris 
1258f11c7f63SJim Harris    sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len);
1259f11c7f63SJim Harris 
1260f11c7f63SJim Harris    information_buff[2] = sati_get_ata_lba_high_ext(register_fis);
1261f11c7f63SJim Harris    information_buff[3] = sati_get_ata_lba_mid_ext(register_fis);
1262f11c7f63SJim Harris    information_buff[4] = sati_get_ata_lba_low_ext(register_fis);
1263f11c7f63SJim Harris    information_buff[5] = sati_get_ata_lba_high(register_fis);
1264f11c7f63SJim Harris    information_buff[6] = sati_get_ata_lba_mid(register_fis);
1265f11c7f63SJim Harris    information_buff[7] = sati_get_ata_lba_low(register_fis);
1266f11c7f63SJim Harris 
1267f11c7f63SJim Harris    sati_set_sense_data_byte(
1268f11c7f63SJim Harris       sense_data,
1269f11c7f63SJim Harris       sense_len,
1270f11c7f63SJim Harris       0,
1271f11c7f63SJim Harris       SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE
1272f11c7f63SJim Harris    );
1273f11c7f63SJim Harris 
1274f11c7f63SJim Harris    sati_scsi_common_descriptor_sense_construct(
1275f11c7f63SJim Harris       sequence,
1276f11c7f63SJim Harris       scsi_io,
1277f11c7f63SJim Harris       sense_data,
1278f11c7f63SJim Harris       sense_len,
1279f11c7f63SJim Harris       sense_key,
1280f11c7f63SJim Harris       additional_sense_code,
1281f11c7f63SJim Harris       additional_sense_code_qualifier,
1282f11c7f63SJim Harris       information_buff
1283f11c7f63SJim Harris    );
1284f11c7f63SJim Harris }
1285f11c7f63SJim Harris 
1286f11c7f63SJim Harris /**
1287f11c7f63SJim Harris * @brief This method will construct the sense data buffer in the user's
1288f11c7f63SJim Harris *        sense data buffer location.  Additionally, it will set the user's
1289f11c7f63SJim Harris *        SCSI status. This is used for uncorrectable read errors.
1290f11c7f63SJim Harris *
1291f11c7f63SJim Harris * @param[in]     sequence This parameter specifies the translation sequence
1292f11c7f63SJim Harris *                for which to construct the sense data.
1293f11c7f63SJim Harris * @param[in,out] scsi_io This parameter specifies the user's IO request
1294f11c7f63SJim Harris *                for which to construct the sense data.
1295f11c7f63SJim Harris * @param[in]     ata_io This parameter is a pointer to the ATA IO data used
1296f11c7f63SJim Harris *                to get the ATA register fis.
1297f11c7f63SJim Harris * @param[in]     scsi_status This parameter specifies the SCSI status
1298f11c7f63SJim Harris *                value for the user's IO request.
1299f11c7f63SJim Harris * @param[in]     sense_key This parameter specifies the sense key to
1300f11c7f63SJim Harris *                be set for the user's IO request.
1301f11c7f63SJim Harris * @param[in]     additional_sense_code This parameter specifies the
1302f11c7f63SJim Harris *                additional sense code (ASC) key to be set for the user's
1303f11c7f63SJim Harris *                IO request.
1304f11c7f63SJim Harris * @param[in]     additional_sense_code_qualifier This parameter specifies
1305f11c7f63SJim Harris *                the additional sense code qualifier (ASCQ) key to be set
1306f11c7f63SJim Harris *                for the user's IO request.
1307f11c7f63SJim Harris *
1308f11c7f63SJim Harris * @return none
1309f11c7f63SJim Harris */
1310f11c7f63SJim Harris static
sati_scsi_read_error_fixed_sense_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io,U8 scsi_status,U8 response_code,U8 sense_key,U8 additional_sense_code,U8 additional_sense_code_qualifier)1311f11c7f63SJim Harris void sati_scsi_read_error_fixed_sense_construct(
1312f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1313f11c7f63SJim Harris    void                       * scsi_io,
1314f11c7f63SJim Harris    void                       * ata_io,
1315f11c7f63SJim Harris    U8                           scsi_status,
1316f11c7f63SJim Harris    U8                           response_code,
1317f11c7f63SJim Harris    U8                           sense_key,
1318f11c7f63SJim Harris    U8                           additional_sense_code,
1319f11c7f63SJim Harris    U8                           additional_sense_code_qualifier
1320f11c7f63SJim Harris )
1321f11c7f63SJim Harris {
1322f11c7f63SJim Harris    U8 * sense_data;
1323f11c7f63SJim Harris    U32  sense_len;
1324f11c7f63SJim Harris    U8   valid = TRUE;
1325f11c7f63SJim Harris 
1326f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
1327f11c7f63SJim Harris 
1328f11c7f63SJim Harris    sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len);
1329f11c7f63SJim Harris 
1330f11c7f63SJim Harris    if(sati_get_ata_lba_mid_ext(register_fis) > 0)
1331f11c7f63SJim Harris    {
1332f11c7f63SJim Harris       valid = FALSE;
1333f11c7f63SJim Harris    }
1334f11c7f63SJim Harris 
1335f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 3,  sati_get_ata_lba_low_ext(register_fis));
1336f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 4,  sati_get_ata_lba_high(register_fis));
1337f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 5,  sati_get_ata_lba_mid(register_fis));
1338f11c7f63SJim Harris    sati_set_sense_data_byte(sense_data, sense_len, 6,  sati_get_ata_lba_low(register_fis));
1339f11c7f63SJim Harris 
1340f11c7f63SJim Harris 
1341f11c7f63SJim Harris    sati_set_sense_data_byte(
1342f11c7f63SJim Harris       sense_data,
1343f11c7f63SJim Harris       sense_len,
1344f11c7f63SJim Harris       0,
1345f11c7f63SJim Harris       (valid << 7) | SCSI_FIXED_CURRENT_RESPONSE_CODE
1346f11c7f63SJim Harris    );
1347f11c7f63SJim Harris 
1348f11c7f63SJim Harris    sati_scsi_common_fixed_sense_construct(
1349f11c7f63SJim Harris       sense_data,
1350f11c7f63SJim Harris       sense_len,
1351f11c7f63SJim Harris       sense_key,
1352f11c7f63SJim Harris       additional_sense_code,
1353f11c7f63SJim Harris       additional_sense_code_qualifier
1354f11c7f63SJim Harris    );
1355f11c7f63SJim Harris }
1356f11c7f63SJim Harris 
sati_scsi_read_error_sense_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_input_data,U8 scsi_status,U8 sense_key,U8 additional_sense_code,U8 additional_sense_code_qualifier)1357f11c7f63SJim Harris void sati_scsi_read_error_sense_construct(
1358f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1359f11c7f63SJim Harris    void                       * scsi_io,
1360f11c7f63SJim Harris    void                       * ata_input_data,
1361f11c7f63SJim Harris    U8                           scsi_status,
1362f11c7f63SJim Harris    U8                           sense_key,
1363f11c7f63SJim Harris    U8                           additional_sense_code,
1364f11c7f63SJim Harris    U8                           additional_sense_code_qualifier
1365f11c7f63SJim Harris )
1366f11c7f63SJim Harris {
1367f11c7f63SJim Harris     U8 response_code;
1368f11c7f63SJim Harris 
1369f11c7f63SJim Harris     response_code = sati_scsi_get_sense_data_response_code(sequence);
1370f11c7f63SJim Harris 
1371f11c7f63SJim Harris     switch (response_code)
1372f11c7f63SJim Harris     {
1373f11c7f63SJim Harris     case SCSI_FIXED_CURRENT_RESPONSE_CODE:
1374f11c7f63SJim Harris     case SCSI_FIXED_DEFERRED_RESPONSE_CODE:
1375f11c7f63SJim Harris         sati_scsi_read_error_fixed_sense_construct(sequence, scsi_io, ata_input_data, scsi_status,
1376f11c7f63SJim Harris                 response_code, sense_key, additional_sense_code, additional_sense_code_qualifier);
1377f11c7f63SJim Harris     break;
1378f11c7f63SJim Harris     case SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE:
1379f11c7f63SJim Harris     case SCSI_DESCRIPTOR_DEFERRED_RESPONSE_CODE:
1380f11c7f63SJim Harris         sati_scsi_read_error_descriptor_sense_construct(sequence, scsi_io, ata_input_data, scsi_status,
1381f11c7f63SJim Harris                 response_code, sense_key, additional_sense_code, additional_sense_code_qualifier);
1382f11c7f63SJim Harris         break;
1383f11c7f63SJim Harris     }
1384f11c7f63SJim Harris 
1385f11c7f63SJim Harris     sequence->is_sense_response_set = TRUE;
1386f11c7f63SJim Harris }
1387f11c7f63SJim Harris 
1388f11c7f63SJim Harris /*
1389f11c7f63SJim Harris  * @brief This method builds the scsi response data for a sata task management
1390f11c7f63SJim Harris  *        request.
1391f11c7f63SJim Harris  *
1392f11c7f63SJim Harris  * @param[in]     sequence This parameter specifies the translation sequence
1393f11c7f63SJim Harris  *                for which to construct the sense data.
1394f11c7f63SJim Harris  * @param[in,out] scsi_io This parameter specifies the user's IO request
1395f11c7f63SJim Harris  *                for which to construct the sense data.
1396f11c7f63SJim Harris  * @param[in]     response_data The response status for the task management
1397f11c7f63SJim Harris  *                request.
1398f11c7f63SJim Harris  */
sati_scsi_response_data_construct(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,U8 response_data)1399f11c7f63SJim Harris void sati_scsi_response_data_construct(
1400f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1401f11c7f63SJim Harris    void                       * scsi_io,
1402f11c7f63SJim Harris    U8                           response_data
1403f11c7f63SJim Harris )
1404f11c7f63SJim Harris {
1405f11c7f63SJim Harris #ifdef SATI_TRANSPORT_SUPPORTS_SAS
1406f11c7f63SJim Harris    SCI_SSP_RESPONSE_IU_T * rsp_iu  = (SCI_SSP_RESPONSE_IU_T*)
1407f11c7f63SJim Harris                                         sati_cb_get_response_iu_address(scsi_io);
1408f11c7f63SJim Harris    rsp_iu->data_present            = 0x01;
1409f11c7f63SJim Harris    rsp_iu->response_data_length[3] = sizeof(U32);
1410f11c7f63SJim Harris    rsp_iu->status                  = 0;
1411f11c7f63SJim Harris    ((U8 *)rsp_iu->data)[3]         = response_data;
1412f11c7f63SJim Harris #else
1413f11c7f63SJim Harris #endif // SATI_TRANSPORT_SUPPORTS_SAS
1414f11c7f63SJim Harris }
1415f11c7f63SJim Harris 
1416f11c7f63SJim Harris /**
1417f11c7f63SJim Harris  * @brief This method checks to make sure that the translation isn't
1418f11c7f63SJim Harris  *        exceeding the allocation length specified in the CDB prior
1419f11c7f63SJim Harris  *        to retrieving the payload data byte from the user's buffer.
1420f11c7f63SJim Harris  *
1421f11c7f63SJim Harris  * @param[in,out] scsi_io This parameter specifies the user's IO request
1422f11c7f63SJim Harris  *                for which to set the user payload data byte.
1423f11c7f63SJim Harris  * @param[in]     byte_offset This parameter specifies the offset into
1424f11c7f63SJim Harris  *                the user's payload buffer at which to write the supplied
1425f11c7f63SJim Harris  *                value.
1426f11c7f63SJim Harris  * @param[in]     value This parameter specifies the memory location into
1427f11c7f63SJim Harris  *                which to read the value from the user's payload buffer.
1428f11c7f63SJim Harris  *
1429f11c7f63SJim Harris  * @return none
1430f11c7f63SJim Harris  */
sati_get_data_byte(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,U32 byte_offset,U8 * value)1431f11c7f63SJim Harris void sati_get_data_byte(
1432f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1433f11c7f63SJim Harris    void                       * scsi_io,
1434f11c7f63SJim Harris    U32                          byte_offset,
1435f11c7f63SJim Harris    U8                         * value
1436f11c7f63SJim Harris )
1437f11c7f63SJim Harris {
1438f11c7f63SJim Harris    if (byte_offset < sequence->allocation_length)
1439f11c7f63SJim Harris       sati_cb_get_data_byte(scsi_io, byte_offset, value);
1440f11c7f63SJim Harris }
1441f11c7f63SJim Harris 
1442f11c7f63SJim Harris /**
1443f11c7f63SJim Harris  * @brief This method checks to make sure that the translation isn't
1444f11c7f63SJim Harris  *        exceeding the allocation length specified in the CDB while
1445f11c7f63SJim Harris  *        translating payload data into the user's buffer.
1446f11c7f63SJim Harris  *
1447f11c7f63SJim Harris  * @param[in]     sequence This parameter specifies the translation sequence
1448f11c7f63SJim Harris  *                for which to set the user payload data byte.
1449f11c7f63SJim Harris  * @param[in,out] scsi_io This parameter specifies the user's IO request
1450f11c7f63SJim Harris  *                for which to set the user payload data byte.
1451f11c7f63SJim Harris  * @param[in]     byte_offset This parameter specifies the offset into
1452f11c7f63SJim Harris  *                the user's payload buffer at which to write the supplied
1453f11c7f63SJim Harris  *                value.
1454f11c7f63SJim Harris  * @param[in]     value This parameter specifies the new value to be
1455f11c7f63SJim Harris  *                written out into the user's payload buffer.
1456f11c7f63SJim Harris  *
1457f11c7f63SJim Harris  * @return none
1458f11c7f63SJim Harris  */
sati_set_data_byte(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,U32 byte_offset,U8 value)1459f11c7f63SJim Harris void sati_set_data_byte(
1460f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1461f11c7f63SJim Harris    void                       * scsi_io,
1462f11c7f63SJim Harris    U32                          byte_offset,
1463f11c7f63SJim Harris    U8                           value
1464f11c7f63SJim Harris )
1465f11c7f63SJim Harris {
1466f11c7f63SJim Harris    if (byte_offset < sequence->allocation_length)
1467f11c7f63SJim Harris    {
1468f11c7f63SJim Harris       sequence->number_data_bytes_set++;
1469f11c7f63SJim Harris       sati_cb_set_data_byte(scsi_io, byte_offset, value);
1470f11c7f63SJim Harris    }
1471f11c7f63SJim Harris }
1472f11c7f63SJim Harris 
1473f11c7f63SJim Harris /**
1474f11c7f63SJim Harris  * @brief This method checks to make sure that the translation isn't
1475f11c7f63SJim Harris  *        exceeding the allocation length specified in the CDB while
1476f11c7f63SJim Harris  *        translating payload data into the user's buffer.
1477f11c7f63SJim Harris  *
1478f11c7f63SJim Harris  * @param[in]     sequence This parameter specifies the translation sequence
1479f11c7f63SJim Harris  *                for which to set the user payload data dword.
1480f11c7f63SJim Harris  * @param[in,out] scsi_io This parameter specifies the user's IO request
1481f11c7f63SJim Harris  *                for which to set the user payload data dword.
1482f11c7f63SJim Harris  * @param[in]     byte_offset This parameter specifies the offset into
1483f11c7f63SJim Harris  *                the user's payload buffer at which to write the supplied
1484f11c7f63SJim Harris  *                value.
1485f11c7f63SJim Harris  * @param[in]     value This parameter specifies the new value to be
1486f11c7f63SJim Harris  *                written out into the user's payload buffer.
1487f11c7f63SJim Harris  *
1488f11c7f63SJim Harris  * @return none
1489f11c7f63SJim Harris  */
sati_set_data_dword(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,U32 byte_offset,U32 value)1490f11c7f63SJim Harris void sati_set_data_dword(
1491f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1492f11c7f63SJim Harris    void                       * scsi_io,
1493f11c7f63SJim Harris    U32                          byte_offset,
1494f11c7f63SJim Harris    U32                          value
1495f11c7f63SJim Harris )
1496f11c7f63SJim Harris {
1497f11c7f63SJim Harris    /// @todo Check to ensure that the bytes appear correctly (SAS Address).
1498f11c7f63SJim Harris 
1499f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, (U8)value & 0xFF);
1500f11c7f63SJim Harris        byte_offset++;
1501f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, (U8)(value >> 8) & 0xFF);
1502f11c7f63SJim Harris        byte_offset++;
1503f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, (U8)(value >> 16) & 0xFF);
1504f11c7f63SJim Harris        byte_offset++;
1505f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, (U8)(value >> 24) & 0xFF);
1506f11c7f63SJim Harris }
1507f11c7f63SJim Harris 
1508f11c7f63SJim Harris /**
1509f11c7f63SJim Harris  * @brief This method will construct the ATA flush cache command.
1510f11c7f63SJim Harris  *
1511f11c7f63SJim Harris  * @pre It is expected that the user has properly set the current contents
1512f11c7f63SJim Harris  *      of the register FIS to 0.
1513f11c7f63SJim Harris  *
1514f11c7f63SJim Harris  * @param[out] ata_io This parameter specifies the ATA IO request structure
1515f11c7f63SJim Harris  *             for which to build the FLUSH CACHE command.
1516f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
1517f11c7f63SJim Harris  *             for which the command is being constructed.
1518f11c7f63SJim Harris  *
1519f11c7f63SJim Harris  * @return none.
1520f11c7f63SJim Harris  */
sati_ata_flush_cache_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)1521f11c7f63SJim Harris void sati_ata_flush_cache_construct(
1522f11c7f63SJim Harris    void                       * ata_io,
1523f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
1524f11c7f63SJim Harris )
1525f11c7f63SJim Harris {
1526f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1527f11c7f63SJim Harris 
1528f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_FLUSH_CACHE);
1529f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
1530f11c7f63SJim Harris }
1531f11c7f63SJim Harris 
1532f11c7f63SJim Harris /**
1533f11c7f63SJim Harris  * @brief This method will construct the ATA standby immediate command.
1534f11c7f63SJim Harris  *
1535f11c7f63SJim Harris  * @pre It is expected that the user has properly set the current contents
1536f11c7f63SJim Harris  *      of the register FIS to 0.
1537f11c7f63SJim Harris  *
1538f11c7f63SJim Harris  * @param[out] ata_io This parameter specifies the ATA IO request structure
1539f11c7f63SJim Harris  *             for which to build the STANDBY IMMEDIATE command.
1540f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
1541f11c7f63SJim Harris  *             for which the command is being constructed.
1542f11c7f63SJim Harris  *
1543f11c7f63SJim Harris  * @param[in]  count This parameter specifies the time period programmed
1544f11c7f63SJim Harris  *             into the Standby Timer. See ATA8 spec for more details
1545f11c7f63SJim Harris  * @return none.
1546f11c7f63SJim Harris  */
sati_ata_standby_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence,U16 count)1547f11c7f63SJim Harris void sati_ata_standby_construct(
1548f11c7f63SJim Harris    void                       * ata_io,
1549f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1550f11c7f63SJim Harris    U16                          count
1551f11c7f63SJim Harris )
1552f11c7f63SJim Harris {
1553f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1554f11c7f63SJim Harris 
1555f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_STANDBY);
1556f11c7f63SJim Harris    sati_set_ata_sector_count(register_fis, count);
1557f11c7f63SJim Harris 
1558f11c7f63SJim Harris    sequence->device->ata_standby_timer = (U8) count;
1559f11c7f63SJim Harris 
1560f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
1561f11c7f63SJim Harris }
1562f11c7f63SJim Harris 
1563f11c7f63SJim Harris /**
1564f11c7f63SJim Harris  * @brief This method will construct the ATA standby immediate command.
1565f11c7f63SJim Harris  *
1566f11c7f63SJim Harris  * @pre It is expected that the user has properly set the current contents
1567f11c7f63SJim Harris  *      of the register FIS to 0.
1568f11c7f63SJim Harris  *
1569f11c7f63SJim Harris  * @param[out] ata_io This parameter specifies the ATA IO request structure
1570f11c7f63SJim Harris  *             for which to build the STANDBY IMMEDIATE command.
1571f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
1572f11c7f63SJim Harris  *             for which the command is being constructed.
1573f11c7f63SJim Harris  *
1574f11c7f63SJim Harris  * @return none.
1575f11c7f63SJim Harris  */
sati_ata_standby_immediate_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)1576f11c7f63SJim Harris void sati_ata_standby_immediate_construct(
1577f11c7f63SJim Harris    void                       * ata_io,
1578f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
1579f11c7f63SJim Harris )
1580f11c7f63SJim Harris {
1581f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1582f11c7f63SJim Harris 
1583f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_STANDBY_IMMED);
1584f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
1585f11c7f63SJim Harris }
1586f11c7f63SJim Harris 
1587f11c7f63SJim Harris /**
1588f11c7f63SJim Harris  * @brief This method will construct the ATA idle immediate command.
1589f11c7f63SJim Harris  *
1590f11c7f63SJim Harris  * @pre It is expected that the user has properly set the current contents
1591f11c7f63SJim Harris  *      of the register FIS to 0.
1592f11c7f63SJim Harris  *
1593f11c7f63SJim Harris  * @param[out] ata_io This parameter specifies the ATA IO request structure
1594f11c7f63SJim Harris  *             for which to build the IDLE IMMEDIATE command.
1595f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
1596f11c7f63SJim Harris  *             for which the command is being constructed.
1597f11c7f63SJim Harris  *
1598f11c7f63SJim Harris  * @return none.
1599f11c7f63SJim Harris  */
sati_ata_idle_immediate_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)1600f11c7f63SJim Harris void sati_ata_idle_immediate_construct(
1601f11c7f63SJim Harris    void                       * ata_io,
1602f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
1603f11c7f63SJim Harris )
1604f11c7f63SJim Harris {
1605f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1606f11c7f63SJim Harris 
1607f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_IDLE_IMMED);
1608f11c7f63SJim Harris    sati_set_ata_features(register_fis, 0x00);
1609f11c7f63SJim Harris    sati_set_ata_sector_count(register_fis, 0x00);
1610f11c7f63SJim Harris    sati_set_ata_lba_high(register_fis, 0x00);
1611f11c7f63SJim Harris    sati_set_ata_lba_mid(register_fis, 0x00);
1612f11c7f63SJim Harris    sati_set_ata_lba_low(register_fis, 0x00);
1613f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
1614f11c7f63SJim Harris }
1615f11c7f63SJim Harris 
1616f11c7f63SJim Harris /**
1617f11c7f63SJim Harris  * @brief This method will construct the ATA idle immediate command
1618f11c7f63SJim Harris           for Unload Features.
1619f11c7f63SJim Harris  *
1620f11c7f63SJim Harris  * @pre It is expected that the user has properly set the current contents
1621f11c7f63SJim Harris  *      of the register FIS to 0.
1622f11c7f63SJim Harris  *
1623f11c7f63SJim Harris  * @param[out] ata_io This parameter specifies the ATA IO request structure
1624f11c7f63SJim Harris  *             for which to build the IDLE IMMEDIATE command.
1625f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
1626f11c7f63SJim Harris  *             for which the command is being constructed.
1627f11c7f63SJim Harris  *
1628f11c7f63SJim Harris  * @return none.
1629f11c7f63SJim Harris  */
sati_ata_idle_immediate_unload_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)1630f11c7f63SJim Harris void sati_ata_idle_immediate_unload_construct(
1631f11c7f63SJim Harris    void                       * ata_io,
1632f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
1633f11c7f63SJim Harris )
1634f11c7f63SJim Harris {
1635f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1636f11c7f63SJim Harris 
1637f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_IDLE_IMMED);
1638f11c7f63SJim Harris    sati_set_ata_features(register_fis, 0x44);
1639f11c7f63SJim Harris    sati_set_ata_sector_count(register_fis, 0x00);
1640f11c7f63SJim Harris    sati_set_ata_lba_high(register_fis, 0x55);
1641f11c7f63SJim Harris    sati_set_ata_lba_mid(register_fis, 0x4E);
1642f11c7f63SJim Harris    sati_set_ata_lba_low(register_fis, 0x4C);
1643f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
1644f11c7f63SJim Harris }
1645f11c7f63SJim Harris 
1646f11c7f63SJim Harris /**
1647f11c7f63SJim Harris  * @brief This method will construct the ATA IDLE command.\
1648f11c7f63SJim Harris  *
1649f11c7f63SJim Harris  * @pre It is expected that the user has properly set the current contents
1650f11c7f63SJim Harris  *      of the register FIS to 0.
1651f11c7f63SJim Harris  *
1652f11c7f63SJim Harris  * @param[out] ata_io This parameter specifies the ATA IO request structure
1653f11c7f63SJim Harris  *             for which to build the ATA IDLE command.
1654f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
1655f11c7f63SJim Harris  *             for which the command is being constructed.
1656f11c7f63SJim Harris  *
1657f11c7f63SJim Harris  * @return none.
1658f11c7f63SJim Harris  */
sati_ata_idle_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)1659f11c7f63SJim Harris void sati_ata_idle_construct(
1660f11c7f63SJim Harris    void                       * ata_io,
1661f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
1662f11c7f63SJim Harris )
1663f11c7f63SJim Harris {
1664f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1665f11c7f63SJim Harris 
1666f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_IDLE);
1667f11c7f63SJim Harris    sati_set_ata_features(register_fis, 0x00);
1668f11c7f63SJim Harris    sati_set_ata_sector_count(register_fis, 0x00);
1669f11c7f63SJim Harris 
1670f11c7f63SJim Harris    sequence->device->ata_standby_timer = 0x00;
1671f11c7f63SJim Harris 
1672f11c7f63SJim Harris    sati_set_ata_lba_high(register_fis, 0x00);
1673f11c7f63SJim Harris    sati_set_ata_lba_mid(register_fis, 0x00);
1674f11c7f63SJim Harris    sati_set_ata_lba_low(register_fis, 0x00);
1675f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
1676f11c7f63SJim Harris }
1677f11c7f63SJim Harris 
1678f11c7f63SJim Harris /**
1679f11c7f63SJim Harris  * @brief This method will construct the ATA MEDIA EJECT command.
1680f11c7f63SJim Harris  *
1681f11c7f63SJim Harris  * @pre It is expected that the user has properly set the current contents
1682f11c7f63SJim Harris  *      of the register FIS to 0.
1683f11c7f63SJim Harris  *
1684f11c7f63SJim Harris  * @param[out] ata_io This parameter specifies the ATA IO request structure
1685f11c7f63SJim Harris  *             for which to build the MEDIA EJCT command.
1686f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
1687f11c7f63SJim Harris  *             for which the command is being constructed.
1688f11c7f63SJim Harris  *
1689f11c7f63SJim Harris  * @return none.
1690f11c7f63SJim Harris  */
sati_ata_media_eject_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)1691f11c7f63SJim Harris void sati_ata_media_eject_construct(
1692f11c7f63SJim Harris    void                       * ata_io,
1693f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
1694f11c7f63SJim Harris )
1695f11c7f63SJim Harris {
1696f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1697f11c7f63SJim Harris 
1698f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_MEDIA_EJECT);
1699f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
1700f11c7f63SJim Harris }
1701f11c7f63SJim Harris 
1702f11c7f63SJim Harris 
1703f11c7f63SJim Harris /**
1704f11c7f63SJim Harris  * @brief This method will construct the ATA read verify sector(s) command.
1705f11c7f63SJim Harris  *
1706f11c7f63SJim Harris  * @pre It is expected that the user has properly set the current contents
1707f11c7f63SJim Harris  *      of the register FIS to 0.
1708f11c7f63SJim Harris  *
1709f11c7f63SJim Harris  * @param[out] ata_io This parameter specifies the ATA IO request structure
1710f11c7f63SJim Harris  *             for which to build the ATA READ VERIFY SECTOR(S) command.
1711f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
1712f11c7f63SJim Harris  *             for which the command is being constructed.
1713f11c7f63SJim Harris  *
1714f11c7f63SJim Harris  * @return none.
1715f11c7f63SJim Harris  */
sati_ata_read_verify_sectors_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)1716f11c7f63SJim Harris void sati_ata_read_verify_sectors_construct(
1717f11c7f63SJim Harris    void                       * ata_io,
1718f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
1719f11c7f63SJim Harris )
1720f11c7f63SJim Harris {
1721f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1722f11c7f63SJim Harris 
1723f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS);
1724f11c7f63SJim Harris 
1725f11c7f63SJim Harris    //According to SAT-2 (v7) 9.11.3
1726f11c7f63SJim Harris    sati_set_ata_sector_count(register_fis, 1);
1727f11c7f63SJim Harris 
1728f11c7f63SJim Harris    //According to SAT-2 (v7) 9.11.3, set LBA to a value between zero and the
1729f11c7f63SJim Harris    //maximum LBA supported by the ATA device in its current configuration.
1730f11c7f63SJim Harris    //From the unit test, it seems we have to set LBA to a non-zero value.
1731f11c7f63SJim Harris    sati_set_ata_lba_low(register_fis, 1);
1732f11c7f63SJim Harris 
1733f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
1734f11c7f63SJim Harris }
1735f11c7f63SJim Harris 
1736f11c7f63SJim Harris /**
1737f11c7f63SJim Harris  * @brief This method will construct a ATA SMART Return Status command so the
1738f11c7f63SJim Harris  *        status of the ATA device can be returned. The status of the SMART
1739f11c7f63SJim Harris  *        threshold will be returned by this command.
1740f11c7f63SJim Harris  *
1741f11c7f63SJim Harris  * @return N/A
1742f11c7f63SJim Harris  *
1743f11c7f63SJim Harris  */
sati_ata_smart_return_status_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence,U8 feature_value)1744f11c7f63SJim Harris void sati_ata_smart_return_status_construct(
1745f11c7f63SJim Harris    void                       * ata_io,
1746f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1747f11c7f63SJim Harris    U8                           feature_value
1748f11c7f63SJim Harris )
1749f11c7f63SJim Harris {
1750f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1751f11c7f63SJim Harris 
1752f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_SMART);
1753f11c7f63SJim Harris 
1754f11c7f63SJim Harris    sati_set_ata_features(register_fis, feature_value);
1755f11c7f63SJim Harris 
1756f11c7f63SJim Harris    sati_set_ata_lba_high(register_fis, 0xC2);
1757f11c7f63SJim Harris    sati_set_ata_lba_mid(register_fis, 0x4F);
1758f11c7f63SJim Harris 
1759f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
1760f11c7f63SJim Harris }
1761f11c7f63SJim Harris 
1762f11c7f63SJim Harris /**
1763f11c7f63SJim Harris  * @brief This method will construct a ATA SMART Return Status command so the
1764f11c7f63SJim Harris  *        status of the ATA device can be returned. The status of the SMART
1765f11c7f63SJim Harris  *        threshold will be returned by this command.
1766f11c7f63SJim Harris  *
1767f11c7f63SJim Harris  * @return N/A
1768f11c7f63SJim Harris  *
1769f11c7f63SJim Harris  */
sati_ata_smart_read_log_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence,U8 log_address,U32 transfer_length)1770f11c7f63SJim Harris void sati_ata_smart_read_log_construct(
1771f11c7f63SJim Harris    void                       * ata_io,
1772f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1773f11c7f63SJim Harris    U8                           log_address,
1774f11c7f63SJim Harris    U32                          transfer_length
1775f11c7f63SJim Harris )
1776f11c7f63SJim Harris {
1777f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1778f11c7f63SJim Harris 
1779f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_SMART);
1780f11c7f63SJim Harris    sati_set_ata_features(register_fis, ATA_SMART_SUB_CMD_READ_LOG);
1781f11c7f63SJim Harris 
1782f11c7f63SJim Harris    sati_set_ata_lba_high(register_fis, 0xC2);
1783f11c7f63SJim Harris    sati_set_ata_lba_mid(register_fis, 0x4F);
1784f11c7f63SJim Harris    sati_set_ata_lba_low(register_fis, log_address);
1785f11c7f63SJim Harris 
1786f11c7f63SJim Harris    sequence->data_direction      = SATI_DATA_DIRECTION_IN;
1787f11c7f63SJim Harris    sequence->protocol            = SAT_PROTOCOL_PIO_DATA_IN;
1788f11c7f63SJim Harris    sequence->ata_transfer_length = transfer_length;
1789f11c7f63SJim Harris }
1790f11c7f63SJim Harris 
1791f11c7f63SJim Harris /**
1792f11c7f63SJim Harris  * @brief This method will construct a Write Uncorrectable ATA command that
1793453130d9SPedro F. Giffuni  *        will write one sector with a pseudo or flagged error. The type of
1794f11c7f63SJim Harris  *        error is specified by the feature value.
1795f11c7f63SJim Harris  *
1796f11c7f63SJim Harris  * @return N/A
1797f11c7f63SJim Harris  *
1798f11c7f63SJim Harris  */
sati_ata_write_uncorrectable_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence,U8 feature_value)1799f11c7f63SJim Harris void sati_ata_write_uncorrectable_construct(
1800f11c7f63SJim Harris    void                       * ata_io,
1801f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1802f11c7f63SJim Harris    U8                           feature_value
1803f11c7f63SJim Harris )
1804f11c7f63SJim Harris {
1805f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1806f11c7f63SJim Harris 
1807f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_WRITE_UNCORRECTABLE);
1808f11c7f63SJim Harris    sati_set_ata_features(register_fis, feature_value);
1809f11c7f63SJim Harris    sati_set_ata_sector_count(register_fis, 0x0001);
1810f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
1811f11c7f63SJim Harris }
1812f11c7f63SJim Harris 
1813f11c7f63SJim Harris /**
1814f11c7f63SJim Harris  * @brief This method will construct a Mode Select ATA SET FEATURES command
1815f11c7f63SJim Harris  *        For example, Enable/Disable Write Cache, Enable/Disable Read Ahead
1816f11c7f63SJim Harris  *
1817f11c7f63SJim Harris  * @return N/A
1818f11c7f63SJim Harris  *
1819f11c7f63SJim Harris  */
sati_ata_set_features_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence,U8 feature)1820f11c7f63SJim Harris void sati_ata_set_features_construct(
1821f11c7f63SJim Harris    void                       * ata_io,
1822f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1823f11c7f63SJim Harris    U8                           feature
1824f11c7f63SJim Harris )
1825f11c7f63SJim Harris {
1826f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1827f11c7f63SJim Harris 
1828f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_SET_FEATURES);
1829f11c7f63SJim Harris    sati_set_ata_features(register_fis, feature);
1830f11c7f63SJim Harris    sati_ata_non_data_command(ata_io, sequence);
1831f11c7f63SJim Harris }
1832f11c7f63SJim Harris 
1833f11c7f63SJim Harris 
1834f11c7f63SJim Harris 
1835f11c7f63SJim Harris /**
1836f11c7f63SJim Harris  * @brief This method will construct a Read Log ext ATA command that
1837f11c7f63SJim Harris  *        will request a log page based on the log_address.
1838f11c7f63SJim Harris  *
1839f11c7f63SJim Harris  * @param[in]  log_address This parameter specifies the log page
1840f11c7f63SJim Harris  *             to be returned from Read Log Ext.
1841f11c7f63SJim Harris  *
1842f11c7f63SJim Harris  * @param[in]  transfer_length This parameter specifies the size of the
1843f11c7f63SJim Harris  *             log page response returned by Read Log Ext.
1844f11c7f63SJim Harris  *
1845f11c7f63SJim Harris  * @return N/A
1846f11c7f63SJim Harris  *
1847f11c7f63SJim Harris  */
sati_ata_read_log_ext_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence,U8 log_address,U32 transfer_length)1848f11c7f63SJim Harris void sati_ata_read_log_ext_construct(
1849f11c7f63SJim Harris    void                          * ata_io,
1850f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T    * sequence,
1851f11c7f63SJim Harris    U8                              log_address,
1852f11c7f63SJim Harris    U32                             transfer_length
1853f11c7f63SJim Harris )
1854f11c7f63SJim Harris {
1855f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1856f11c7f63SJim Harris 
1857f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_READ_LOG_EXT);
1858f11c7f63SJim Harris 
1859f11c7f63SJim Harris    sati_set_ata_lba_low(register_fis, log_address);
1860f11c7f63SJim Harris    sati_set_ata_lba_mid(register_fis, 0x00);
1861f11c7f63SJim Harris    sati_set_ata_lba_mid_exp(register_fis, 0x00);
1862f11c7f63SJim Harris 
1863f11c7f63SJim Harris    sati_set_ata_sector_count(register_fis, 0x01);
1864f11c7f63SJim Harris 
1865f11c7f63SJim Harris    sequence->data_direction      = SATI_DATA_DIRECTION_IN;
1866f11c7f63SJim Harris    sequence->protocol            = SAT_PROTOCOL_PIO_DATA_IN;
1867f11c7f63SJim Harris    sequence->ata_transfer_length = transfer_length;
1868f11c7f63SJim Harris 
1869f11c7f63SJim Harris }
1870f11c7f63SJim Harris 
1871f11c7f63SJim Harris /**
1872f11c7f63SJim Harris * @brief This method will check if the ATA device is in the stopped power
1873f11c7f63SJim Harris *        state. This is used for all medium access commands for SAT
1874f11c7f63SJim Harris *        compliance. See SAT2r07 section 9.11.1
1875f11c7f63SJim Harris *
1876f11c7f63SJim Harris * @param[in] sequence - SATI sequence data with the device state.
1877f11c7f63SJim Harris *
1878f11c7f63SJim Harris * @return TRUE If device is stopped
1879f11c7f63SJim Harris *
1880f11c7f63SJim Harris */
sati_device_state_stopped(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io)1881f11c7f63SJim Harris BOOL sati_device_state_stopped(
1882f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1883f11c7f63SJim Harris    void                       * scsi_io
1884f11c7f63SJim Harris )
1885f11c7f63SJim Harris {
1886f11c7f63SJim Harris    if(sequence->device->state == SATI_DEVICE_STATE_STOPPED)
1887f11c7f63SJim Harris    {
1888f11c7f63SJim Harris       sati_scsi_sense_data_construct(
1889f11c7f63SJim Harris          sequence,
1890f11c7f63SJim Harris          scsi_io,
1891f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
1892f11c7f63SJim Harris          SCSI_SENSE_NOT_READY ,
1893f11c7f63SJim Harris          SCSI_ASC_INITIALIZING_COMMAND_REQUIRED,
1894f11c7f63SJim Harris          SCSI_ASCQ_INITIALIZING_COMMAND_REQUIRED
1895f11c7f63SJim Harris       );
1896f11c7f63SJim Harris       return TRUE;
1897f11c7f63SJim Harris    }
1898f11c7f63SJim Harris    return FALSE;
1899f11c7f63SJim Harris }
1900f11c7f63SJim Harris 
1901f11c7f63SJim Harris /**
1902f11c7f63SJim Harris * @brief This method will construct a ATA Read Buffer command that
1903f11c7f63SJim Harris *        will request PIO in data containing the target device's buffer.
1904f11c7f63SJim Harris *
1905f11c7f63SJim Harris * @param[out] ata_io This parameter specifies the ATA IO request structure
1906f11c7f63SJim Harris *             for which to build the ATA READ VERIFY SECTOR(S) command.
1907f11c7f63SJim Harris * @param[in]  sequence This parameter specifies the translator sequence
1908f11c7f63SJim Harris *             for which the command is being constructed.
1909f11c7f63SJim Harris * @return N/A
1910f11c7f63SJim Harris *
1911f11c7f63SJim Harris */
sati_ata_read_buffer_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)1912f11c7f63SJim Harris void sati_ata_read_buffer_construct(
1913f11c7f63SJim Harris    void                       * ata_io,
1914f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
1915f11c7f63SJim Harris )
1916f11c7f63SJim Harris {
1917f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1918f11c7f63SJim Harris 
1919f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_READ_BUFFER);
1920f11c7f63SJim Harris    sequence->data_direction      = SATI_DATA_DIRECTION_IN;
1921f11c7f63SJim Harris    sequence->protocol            = SAT_PROTOCOL_PIO_DATA_IN;
1922f11c7f63SJim Harris    sequence->ata_transfer_length = 512;
1923f11c7f63SJim Harris }
1924f11c7f63SJim Harris 
1925f11c7f63SJim Harris 
1926f11c7f63SJim Harris /**
1927f11c7f63SJim Harris * @brief This method will construct a ATA Write Buffer command that
1928f11c7f63SJim Harris *        will send PIO out data to the target device's buffer.
1929f11c7f63SJim Harris *
1930f11c7f63SJim Harris * @param[out] ata_io This parameter specifies the ATA IO request structure
1931f11c7f63SJim Harris *             for which to build the ATA READ VERIFY SECTOR(S) command.
1932f11c7f63SJim Harris * @param[in]  sequence This parameter specifies the translator sequence
1933f11c7f63SJim Harris *             for which the command is being constructed.
1934f11c7f63SJim Harris * @return N/A
1935f11c7f63SJim Harris *
1936f11c7f63SJim Harris */
sati_ata_write_buffer_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence)1937f11c7f63SJim Harris void sati_ata_write_buffer_construct(
1938f11c7f63SJim Harris    void                       * ata_io,
1939f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
1940f11c7f63SJim Harris )
1941f11c7f63SJim Harris {
1942f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1943f11c7f63SJim Harris 
1944f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_WRITE_BUFFER);
1945f11c7f63SJim Harris 
1946f11c7f63SJim Harris    sequence->data_direction      = SATI_DATA_DIRECTION_OUT;
1947f11c7f63SJim Harris    sequence->protocol            = SAT_PROTOCOL_PIO_DATA_OUT;
1948f11c7f63SJim Harris    sequence->ata_transfer_length = 512;
1949f11c7f63SJim Harris }
1950f11c7f63SJim Harris 
1951f11c7f63SJim Harris 
1952f11c7f63SJim Harris /**
1953f11c7f63SJim Harris * @brief This method will construct a ATA Download Microcode command that
1954f11c7f63SJim Harris *        will send PIO out data containing new firmware for the target drive.
1955f11c7f63SJim Harris *
1956f11c7f63SJim Harris * @param[out] ata_io This parameter specifies the ATA IO request structure
1957f11c7f63SJim Harris *             for which to build the ATA READ VERIFY SECTOR(S) command.
1958f11c7f63SJim Harris * @param[in]  sequence This parameter specifies the translator sequence
1959f11c7f63SJim Harris *             for which the command is being constructed.
1960f11c7f63SJim Harris * @param[in]  mode This parameter specifies the download microcode sub-command
1961f11c7f63SJim Harris *             code.
1962f11c7f63SJim Harris * @param[in]  allocation_length This parameter specifies the number of bytes
1963f11c7f63SJim Harris *             being sent to the target device.
1964f11c7f63SJim Harris * @param[in]  buffer_offset This parameter specifies the buffer offset for the
1965f11c7f63SJim Harris *             data sent to the target device.
1966f11c7f63SJim Harris *
1967f11c7f63SJim Harris * @return N/A
1968f11c7f63SJim Harris *
1969f11c7f63SJim Harris */
sati_ata_download_microcode_construct(void * ata_io,SATI_TRANSLATOR_SEQUENCE_T * sequence,U8 mode,U32 allocation_length,U32 buffer_offset)1970f11c7f63SJim Harris void sati_ata_download_microcode_construct(
1971f11c7f63SJim Harris    void                       * ata_io,
1972f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1973f11c7f63SJim Harris    U8                           mode,
1974f11c7f63SJim Harris    U32                          allocation_length,
1975f11c7f63SJim Harris    U32                          buffer_offset
1976f11c7f63SJim Harris )
1977f11c7f63SJim Harris {
1978f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
1979cc318662SJim Harris    U32 allocation_blocks = allocation_length >> 9;
1980cc318662SJim Harris    U32 buffer_blkoffset = buffer_offset >> 9;
1981f11c7f63SJim Harris 
1982f11c7f63SJim Harris    sati_set_ata_command(register_fis, ATA_DOWNLOAD_MICROCODE);
1983f11c7f63SJim Harris    sati_set_ata_features(register_fis, mode);
1984f11c7f63SJim Harris 
1985f11c7f63SJim Harris    if(mode == ATA_MICROCODE_DOWNLOAD_SAVE)
1986f11c7f63SJim Harris    {
1987f11c7f63SJim Harris       sati_set_ata_sector_count(register_fis, (U8) (allocation_length >> 9));
1988f11c7f63SJim Harris       sati_set_ata_lba_low(register_fis, (U8) (allocation_length >> 17));
1989f11c7f63SJim Harris    }
1990f11c7f63SJim Harris    else //mode == 0x03
1991f11c7f63SJim Harris    {
1992cc318662SJim Harris       sati_set_ata_sector_count(register_fis, (U8) (allocation_blocks & 0xff));
1993cc318662SJim Harris       sati_set_ata_lba_low(register_fis, (U8) ((allocation_blocks >> 8) & 0xff));
1994cc318662SJim Harris       sati_set_ata_lba_mid(register_fis, (U8) (buffer_blkoffset & 0xff));
1995cc318662SJim Harris       sati_set_ata_lba_high(register_fis, (U8) ((buffer_blkoffset >> 8) & 0xff));
1996f11c7f63SJim Harris    }
1997f11c7f63SJim Harris 
1998f11c7f63SJim Harris    if((allocation_length == 0) && (buffer_offset == 0))
1999f11c7f63SJim Harris    {
2000f11c7f63SJim Harris       sati_ata_non_data_command(ata_io, sequence);
2001f11c7f63SJim Harris    }
2002f11c7f63SJim Harris    else
2003f11c7f63SJim Harris    {
2004f11c7f63SJim Harris       sequence->data_direction      = SATI_DATA_DIRECTION_OUT;
2005f11c7f63SJim Harris       sequence->protocol            = SAT_PROTOCOL_PIO_DATA_OUT;
2006f11c7f63SJim Harris       sequence->ata_transfer_length = allocation_length;
2007f11c7f63SJim Harris    }
2008f11c7f63SJim Harris }
2009