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