xref: /freebsd/sys/dev/isci/scil/sati_mode_select.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
1f11c7f63SJim Harris /*-
2*718cf2ccSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3*718cf2ccSPedro 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 the method implementations required to
59f11c7f63SJim Harris  *        translate the SCSI mode select (6 and 10-byte) commands with 5
60f11c7f63SJim Harris  *        supported mode parameter pages (0x01, 0x02, 0x08, 0x0A, 0x1C).
61f11c7f63SJim Harris  */
62f11c7f63SJim Harris 
63f11c7f63SJim Harris #if !defined(DISABLE_SATI_MODE_SELECT)
64f11c7f63SJim Harris 
65f11c7f63SJim Harris #include <dev/isci/scil/sati_mode_select.h>
66f11c7f63SJim Harris #include <dev/isci/scil/sati_mode_pages.h>
67f11c7f63SJim Harris #include <dev/isci/scil/sati_callbacks.h>
68f11c7f63SJim Harris #include <dev/isci/scil/sci_object.h>
69f11c7f63SJim Harris #include <dev/isci/scil/sati_translator_sequence.h>
70f11c7f63SJim Harris #include <dev/isci/scil/sati_util.h>
71f11c7f63SJim Harris 
72f11c7f63SJim Harris //******************************************************************************
73f11c7f63SJim Harris //* P R I V A T E   M E T H O D S
74f11c7f63SJim Harris //******************************************************************************
75f11c7f63SJim Harris 
76f11c7f63SJim Harris /**
77f11c7f63SJim Harris  * @brief This method will get medium type parameter field per CDB size.
78f11c7f63SJim Harris  *
79f11c7f63SJim Harris  * @param[in] scsi_io This parameter specifies the user's SCSI IO object
80f11c7f63SJim Harris  *            for which to calculate the mode page header.
81f11c7f63SJim Harris  * @param[in] cdb_size This parameter specifies the number of bytes
82f11c7f63SJim Harris  *            associated with the CDB for which to calculate the header.
83f11c7f63SJim Harris  *
84f11c7f63SJim Harris  * @return This method returns the medium type for the mode page header.
85f11c7f63SJim Harris  */
86f11c7f63SJim Harris static
sati_mode_select_get_medium_type(U8 * mode_parameters,U32 cdb_size)87f11c7f63SJim Harris U8 sati_mode_select_get_medium_type(
88f11c7f63SJim Harris    U8 * mode_parameters,
89f11c7f63SJim Harris    U32  cdb_size
90f11c7f63SJim Harris )
91f11c7f63SJim Harris {
92f11c7f63SJim Harris    U8  medium_type =0xFF;
93f11c7f63SJim Harris    SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_6_T * mode_parameters_6;
94f11c7f63SJim Harris    SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_10_T * mode_parameters_10;
95f11c7f63SJim Harris 
96f11c7f63SJim Harris    if(cdb_size == 6)
97f11c7f63SJim Harris    {
98f11c7f63SJim Harris       mode_parameters_6 = (SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_6_T *) mode_parameters;
99f11c7f63SJim Harris       medium_type = mode_parameters_6->medium_type;
100f11c7f63SJim Harris    }
101f11c7f63SJim Harris    else if(cdb_size == 10)
102f11c7f63SJim Harris    {
103f11c7f63SJim Harris       mode_parameters_10 = (SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_10_T *) mode_parameters;
104f11c7f63SJim Harris       medium_type = mode_parameters_10->medium_type;
105f11c7f63SJim Harris    }
106f11c7f63SJim Harris 
107f11c7f63SJim Harris    return medium_type;
108f11c7f63SJim Harris }
109f11c7f63SJim Harris 
110f11c7f63SJim Harris /**
111f11c7f63SJim Harris  * @brief This method will retrieve Block Descriptor Length.
112f11c7f63SJim Harris  *
113f11c7f63SJim Harris  * @param[in] mode_parameters This parameter contains the address to the mode parameters.
114f11c7f63SJim Harris  * @param[in] cdb_size This parameter specifies the number of bytes
115f11c7f63SJim Harris  *            associated with the CDB for which to process the block descriptor.
116f11c7f63SJim Harris  *
117f11c7f63SJim Harris  * @return This method returns the size, in bytes, for the mode parameter block descriptor.
118f11c7f63SJim Harris  */
119f11c7f63SJim Harris static
sati_mode_select_get_mode_block_descriptor_length(U8 * mode_parameters,U32 cdb_size)120f11c7f63SJim Harris U32 sati_mode_select_get_mode_block_descriptor_length(
121f11c7f63SJim Harris    U8 * mode_parameters,
122f11c7f63SJim Harris    U32  cdb_size
123f11c7f63SJim Harris )
124f11c7f63SJim Harris {
125f11c7f63SJim Harris    U32 mode_block_descriptor_length = 0;
126f11c7f63SJim Harris    SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_6_T * mode_parameters_6;
127f11c7f63SJim Harris    SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_10_T * mode_parameters_10;
128f11c7f63SJim Harris 
129f11c7f63SJim Harris    if(cdb_size == 6)
130f11c7f63SJim Harris    {
131f11c7f63SJim Harris       mode_parameters_6 = (SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_6_T *) mode_parameters;
132f11c7f63SJim Harris       mode_block_descriptor_length = mode_parameters_6->block_descriptor_length;
133f11c7f63SJim Harris    }
134f11c7f63SJim Harris    else if(cdb_size == 10)
135f11c7f63SJim Harris    {
136f11c7f63SJim Harris       mode_parameters_10 = (SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_10_T *) mode_parameters;
137f11c7f63SJim Harris       //Long LBA bit is the bit0 of the byte
138f11c7f63SJim Harris       //Spec says another way to get the block descriptor length to multiply the block number
139f11c7f63SJim Harris       //   with block length (8 or 16), but we can get it directly.
140f11c7f63SJim Harris       mode_block_descriptor_length =(((U16)mode_parameters_10->block_descriptor_length[0]) << 8) +
141f11c7f63SJim Harris          mode_parameters_10->block_descriptor_length[1];
142f11c7f63SJim Harris 
143f11c7f63SJim Harris    }
144f11c7f63SJim Harris 
145f11c7f63SJim Harris    return mode_block_descriptor_length;
146f11c7f63SJim Harris 
147f11c7f63SJim Harris }
148f11c7f63SJim Harris 
149f11c7f63SJim Harris /**
150f11c7f63SJim Harris  * @brief This method will find the starting byte location for a page.
151f11c7f63SJim Harris  *
152f11c7f63SJim Harris  * @param[in] block_descriptor_length This parameter passes in the length of
153f11c7f63SJim Harris  *            block descriptor.
154f11c7f63SJim Harris  * @param[in] cdb_size This parameter specifies the number of bytes
155f11c7f63SJim Harris  *            associated with the CDB for which to calculate the header.
156f11c7f63SJim Harris  *
157f11c7f63SJim Harris  * @return This method returns the offset, for the mode page.
158f11c7f63SJim Harris  */
159f11c7f63SJim Harris static
sati_mode_select_get_mode_page_offset(U32 block_descriptor_length,U32 cdb_size)160f11c7f63SJim Harris U32 sati_mode_select_get_mode_page_offset(
161f11c7f63SJim Harris     U32 block_descriptor_length,
162f11c7f63SJim Harris     U32 cdb_size
163f11c7f63SJim Harris     )
164f11c7f63SJim Harris {
165f11c7f63SJim Harris    U32 mode_page_offset;
166f11c7f63SJim Harris 
167f11c7f63SJim Harris    if(cdb_size == 6)
168f11c7f63SJim Harris    {
169f11c7f63SJim Harris       mode_page_offset =  sizeof(SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_6_T) +  block_descriptor_length;
170f11c7f63SJim Harris    }
171f11c7f63SJim Harris    else if(cdb_size == 10)
172f11c7f63SJim Harris    {
173f11c7f63SJim Harris       mode_page_offset =  sizeof(SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_10_T) +  block_descriptor_length;
174f11c7f63SJim Harris    }
175f11c7f63SJim Harris    else
176f11c7f63SJim Harris    {
177f11c7f63SJim Harris       mode_page_offset = 0;
178f11c7f63SJim Harris    }
179f11c7f63SJim Harris 
180f11c7f63SJim Harris    return mode_page_offset;
181f11c7f63SJim Harris }
182f11c7f63SJim Harris 
183f11c7f63SJim Harris /**
184f11c7f63SJim Harris  * @brief This method will set the initial Mode Select processing state.
185f11c7f63SJim Harris  */
186f11c7f63SJim Harris static
sati_mode_select_initialize_mode_sel_processing_state(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io,U32 data_transfer_length,U32 mode_page_offset)187f11c7f63SJim Harris void  sati_mode_select_initialize_mode_sel_processing_state(
188f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
189f11c7f63SJim Harris    void                       * scsi_io,
190f11c7f63SJim Harris    void                       * ata_io,
191f11c7f63SJim Harris    U32 data_transfer_length,
192f11c7f63SJim Harris    U32 mode_page_offset
193f11c7f63SJim Harris    )
194f11c7f63SJim Harris {
195f11c7f63SJim Harris    sequence->command_specific_data.process_state.ata_command_sent_for_cmp = 0;
196f11c7f63SJim Harris    sequence->command_specific_data.process_state.mode_page_offset=mode_page_offset;
197f11c7f63SJim Harris    sequence->command_specific_data.process_state.mode_pages_size = data_transfer_length  -  mode_page_offset;
198f11c7f63SJim Harris    sequence->command_specific_data.process_state.size_of_data_processed = 0;
199f11c7f63SJim Harris    sequence->command_specific_data.process_state.current_mode_page_processed = FALSE;
200f11c7f63SJim Harris }
201f11c7f63SJim Harris 
202f11c7f63SJim Harris /**
203f11c7f63SJim Harris  * @brief This method will get mode page size.
204f11c7f63SJim Harris  *
205f11c7f63SJim Harris  * @param[in] page_code This parameter contains page code for the current mode page.
206f11c7f63SJim Harris  *
207f11c7f63SJim Harris  * @return This method returns the size of current mode page.
208f11c7f63SJim Harris  */
209f11c7f63SJim Harris static
sati_mode_select_get_mode_page_size(U8 page_code)210f11c7f63SJim Harris U32 sati_mode_select_get_mode_page_size(
211f11c7f63SJim Harris    U8 page_code
212f11c7f63SJim Harris )
213f11c7f63SJim Harris {
214f11c7f63SJim Harris    U32 page_size=0;
215f11c7f63SJim Harris 
216f11c7f63SJim Harris    switch (page_code)
217f11c7f63SJim Harris    {
218f11c7f63SJim Harris    case SCSI_MODE_PAGE_READ_WRITE_ERROR:
219f11c7f63SJim Harris       page_size=SCSI_MODE_PAGE_01_LENGTH;
220f11c7f63SJim Harris       break;
221f11c7f63SJim Harris 
222f11c7f63SJim Harris    case SCSI_MODE_PAGE_DISCONNECT_RECONNECT:
223f11c7f63SJim Harris       page_size=SCSI_MODE_PAGE_02_LENGTH;
224f11c7f63SJim Harris       break;
225f11c7f63SJim Harris 
226f11c7f63SJim Harris    case SCSI_MODE_PAGE_CACHING:
227f11c7f63SJim Harris       page_size=SCSI_MODE_PAGE_08_LENGTH;
228f11c7f63SJim Harris       break;
229f11c7f63SJim Harris 
230f11c7f63SJim Harris    case SCSI_MODE_PAGE_CONTROL:
231f11c7f63SJim Harris       page_size=SCSI_MODE_PAGE_0A_LENGTH;
232f11c7f63SJim Harris       break;
233f11c7f63SJim Harris 
234f11c7f63SJim Harris    case SCSI_MODE_PAGE_INFORMATIONAL_EXCP_CONTROL:
235f11c7f63SJim Harris       page_size=SCSI_MODE_PAGE_1C_LENGTH;
236f11c7f63SJim Harris       break;
237f11c7f63SJim Harris 
238f11c7f63SJim Harris    case SCSI_MODE_PAGE_POWER_CONDITION:
239f11c7f63SJim Harris       page_size=SCSI_MODE_PAGE_1A_LENGTH;
240f11c7f63SJim Harris       break;
241f11c7f63SJim Harris    default:
242f11c7f63SJim Harris       page_size=0;
243f11c7f63SJim Harris       break;
244f11c7f63SJim Harris    }
245f11c7f63SJim Harris 
246f11c7f63SJim Harris    return page_size;
247f11c7f63SJim Harris }
248f11c7f63SJim Harris 
249f11c7f63SJim Harris /**
250f11c7f63SJim Harris  * @brief This method will check the validity of parameter data of Read Write Error Recovery
251f11c7f63SJim Harris  *            page and further processing the page data if necessary.
252f11c7f63SJim Harris  *
253f11c7f63SJim Harris  * @param[in] page_size This parameter specifies page size of current mode page.
254f11c7f63SJim Harris  *
255f11c7f63SJim Harris  * @return Indicate if the translation was successful.
256f11c7f63SJim Harris  * @retval SATI_SUCCESS
257f11c7f63SJim Harris  * @retval SATI_COMPLETE
258f11c7f63SJim Harris  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
259f11c7f63SJim Harris  */
260f11c7f63SJim Harris static
sati_mode_select_process_mode_page_read_write_error_recovery(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,U32 page_size)261f11c7f63SJim Harris SATI_STATUS sati_mode_select_process_mode_page_read_write_error_recovery(
262f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T* sequence,
263f11c7f63SJim Harris    void     *  scsi_io,
264f11c7f63SJim Harris    U32   page_size
265f11c7f63SJim Harris    )
266f11c7f63SJim Harris {
267f11c7f63SJim Harris    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
268f11c7f63SJim Harris 
269f11c7f63SJim Harris    U8 current_mode_page[SCSI_MODE_PAGE_01_LENGTH]={0,0,0,0,0,0,0,0,0,0,0,0};
270f11c7f63SJim Harris    U32 mode_page_offset;
271f11c7f63SJim Harris 
272f11c7f63SJim Harris    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
273f11c7f63SJim Harris 
274f11c7f63SJim Harris    //Check all the defined bits for this page
275f11c7f63SJim Harris    //SPF(0b); Page length 0x0A;AWRE 1; ARRE 0; Error recovery bits 0; RC 0;
276f11c7f63SJim Harris    //Recovery time limit last two bytes 0
277f11c7f63SJim Harris 
278f11c7f63SJim Harris    sati_get_data_byte(sequence, scsi_io, mode_page_offset,   &current_mode_page[0]);
279f11c7f63SJim Harris    sati_get_data_byte(sequence, scsi_io, mode_page_offset+1, &current_mode_page[1]);
280f11c7f63SJim Harris    sati_get_data_byte(sequence, scsi_io, mode_page_offset+2, &current_mode_page[2]);
281f11c7f63SJim Harris    sati_get_data_byte(sequence, scsi_io, mode_page_offset+10, &current_mode_page[10]);
282f11c7f63SJim Harris    sati_get_data_byte(sequence, scsi_io, mode_page_offset+11, &current_mode_page[11]);
283f11c7f63SJim Harris 
284f11c7f63SJim Harris    if ( ((current_mode_page[0] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK)!= 0) ||
285f11c7f63SJim Harris       (current_mode_page[1] != (SCSI_MODE_PAGE_01_LENGTH - 2)) ||
286f11c7f63SJim Harris       ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_01_AWRE_MASK) == 0) ||
287f11c7f63SJim Harris       ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_01_ARRE_MASK) != 0) ||
288f11c7f63SJim Harris       ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_01_RC_ERBITS_MASK) != 0) ||
289f11c7f63SJim Harris       (current_mode_page[10] != 0 ) ||
290f11c7f63SJim Harris       (current_mode_page[11] != 0 ) )
291f11c7f63SJim Harris    {
292f11c7f63SJim Harris       status = SATI_FAILURE_CHECK_RESPONSE_DATA;
293f11c7f63SJim Harris       return status;
294f11c7f63SJim Harris    }
295f11c7f63SJim Harris 
296f11c7f63SJim Harris    //no need to send any command
297f11c7f63SJim Harris    {
298f11c7f63SJim Harris       sequence->command_specific_data.process_state.size_of_data_processed += page_size;
299f11c7f63SJim Harris       sequence->command_specific_data.process_state.mode_page_offset += page_size;
300f11c7f63SJim Harris       sequence->command_specific_data.process_state.current_mode_page_processed = TRUE;
301f11c7f63SJim Harris    }
302f11c7f63SJim Harris 
303f11c7f63SJim Harris    status = SATI_COMPLETE;
304f11c7f63SJim Harris 
305f11c7f63SJim Harris    return status;
306f11c7f63SJim Harris }
307f11c7f63SJim Harris 
308f11c7f63SJim Harris /**
309f11c7f63SJim Harris  * @brief This method will check the validity of parameter data of Disconnect Reconnect mode
310f11c7f63SJim Harris  *            page and further processing the page data if necessary.
311f11c7f63SJim Harris  *
312f11c7f63SJim Harris  * @param[in] page_size This parameter specifies page size of current mode page.
313f11c7f63SJim Harris  *
314f11c7f63SJim Harris  * @return Indicate if the translation was successful.
315f11c7f63SJim Harris  * @retval SATI_SUCCESS
316f11c7f63SJim Harris  * @retval SATI_COMPLETE
317f11c7f63SJim Harris  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
318f11c7f63SJim Harris  */
319f11c7f63SJim Harris static
sati_mode_select_process_mode_page_disconnect_reconnect(SATI_MODE_SELECT_PROCESSING_STATE_T * mode_select_process_state,U32 page_size)320f11c7f63SJim Harris SATI_STATUS sati_mode_select_process_mode_page_disconnect_reconnect(
321f11c7f63SJim Harris    SATI_MODE_SELECT_PROCESSING_STATE_T * mode_select_process_state,
322f11c7f63SJim Harris    U32 page_size
323f11c7f63SJim Harris    )
324f11c7f63SJim Harris {
325f11c7f63SJim Harris    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
326f11c7f63SJim Harris 
327f11c7f63SJim Harris    // No need to check data for valid or invalid this page (undefined)
328f11c7f63SJim Harris    // No ata command to send
329f11c7f63SJim Harris    {
330f11c7f63SJim Harris       mode_select_process_state->size_of_data_processed += page_size;
331f11c7f63SJim Harris       mode_select_process_state->mode_page_offset += page_size;
332f11c7f63SJim Harris       mode_select_process_state->current_mode_page_processed = TRUE;
333f11c7f63SJim Harris    }
334f11c7f63SJim Harris 
335f11c7f63SJim Harris    // No further interaction with remote devices
336f11c7f63SJim Harris    status = SATI_COMPLETE;
337f11c7f63SJim Harris 
338f11c7f63SJim Harris    return status;
339f11c7f63SJim Harris }
340f11c7f63SJim Harris 
341f11c7f63SJim Harris /**
342f11c7f63SJim Harris  * @brief This method will check the validity of parameter data of Caching mode
343f11c7f63SJim Harris  *            page and issue multiple ATA set feature commands to complete the translation.
344f11c7f63SJim Harris  *
345f11c7f63SJim Harris  * @param[in] page_size This parameter specifies page size of current mode page.
346f11c7f63SJim Harris  *
347f11c7f63SJim Harris  * @return Indicate if the translation was successful.
348f11c7f63SJim Harris  * @retval SATI_SUCCESS
349f11c7f63SJim Harris  * @retval SATI_COMPLETE
350f11c7f63SJim Harris  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
351f11c7f63SJim Harris  */
352f11c7f63SJim Harris static
sati_mode_select_process_mode_page_caching(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io,U32 page_size)353f11c7f63SJim Harris SATI_STATUS sati_mode_select_process_mode_page_caching(
354f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
355f11c7f63SJim Harris    void * scsi_io,
356f11c7f63SJim Harris    void * ata_io,
357f11c7f63SJim Harris    U32 page_size
358f11c7f63SJim Harris    )
359f11c7f63SJim Harris {
360f11c7f63SJim Harris    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
361f11c7f63SJim Harris 
362f11c7f63SJim Harris    //SCSI_MODE_PAGE_08_LENGTH 0x14= 20
363f11c7f63SJim Harris    U8 current_mode_page[SCSI_MODE_PAGE_08_LENGTH] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
364f11c7f63SJim Harris    U32 mode_page_offset;
365f11c7f63SJim Harris    U32 index;
366f11c7f63SJim Harris 
367f11c7f63SJim Harris    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
368f11c7f63SJim Harris    sequence->type = SATI_SEQUENCE_MODE_SELECT_MODE_PAGE_CACHING;
369f11c7f63SJim Harris 
370f11c7f63SJim Harris    for(index = 0; index < SCSI_MODE_PAGE_08_LENGTH; index++)
371f11c7f63SJim Harris    {
372f11c7f63SJim Harris       sati_get_data_byte(sequence, scsi_io, mode_page_offset+index, &current_mode_page[index]);
373f11c7f63SJim Harris    }
374f11c7f63SJim Harris 
375f11c7f63SJim Harris    //Check for data validity
376f11c7f63SJim Harris    //SPF(0b); Page length 0x12;Byte2 to Byte15 all 0 with exception DRA and WCE changeable
377f11c7f63SJim Harris 
378f11c7f63SJim Harris    if (((current_mode_page[0] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK)!= 0) ||
379f11c7f63SJim Harris       (current_mode_page[1] != (SCSI_MODE_PAGE_08_LENGTH-2)) ||
380f11c7f63SJim Harris       ((current_mode_page[2] | SCSI_MODE_PAGE_CACHE_PAGE_WCE_BIT)!=SCSI_MODE_PAGE_CACHE_PAGE_WCE_BIT) ||
381f11c7f63SJim Harris       (current_mode_page[3] != 0 ) ||
382f11c7f63SJim Harris       (current_mode_page[4] != 0 ) ||
383f11c7f63SJim Harris       (current_mode_page[5] != 0 ) ||
384f11c7f63SJim Harris       (current_mode_page[6] != 0 ) ||
385f11c7f63SJim Harris       (current_mode_page[7] != 0 ) ||
386f11c7f63SJim Harris       (current_mode_page[8] != 0 ) ||
387f11c7f63SJim Harris       (current_mode_page[9] != 0 ) ||
388f11c7f63SJim Harris       (current_mode_page[10] != 0 ) ||
389f11c7f63SJim Harris       (current_mode_page[11] != 0 ) ||
390f11c7f63SJim Harris       ((current_mode_page[12] & SCSI_MODE_SELECT_MODE_PAGE_08_FSW_LBCSS_NVDIS) != 0) ||
391f11c7f63SJim Harris       (current_mode_page[13] != 0 ) ||
392f11c7f63SJim Harris       (current_mode_page[14] != 0 ) ||
393f11c7f63SJim Harris       (current_mode_page[15] != 0 ))
394f11c7f63SJim Harris    {
395f11c7f63SJim Harris       //parameter data passed in containing data that doesn't meet the SAT-2 requirement
396f11c7f63SJim Harris       return SATI_FAILURE_CHECK_RESPONSE_DATA;
397f11c7f63SJim Harris    }
398f11c7f63SJim Harris 
399f11c7f63SJim Harris    if(sequence->command_specific_data.process_state.ata_command_sent_for_cmp == 0)
400f11c7f63SJim Harris    {
401f11c7f63SJim Harris       //byte2 bit2 WCE==0 disable write cache WCE==1 enable write cache
402f11c7f63SJim Harris       //SCSI_MODE_PAGE_CACHE_PAGE_WCE_BIT ==0x4,
403f11c7f63SJim Harris 
404f11c7f63SJim Harris       if ( (current_mode_page[2] & SCSI_MODE_PAGE_CACHE_PAGE_WCE_BIT) == 0)
405f11c7f63SJim Harris          sati_ata_set_features_construct(ata_io, sequence, ATA_SET_FEATURES_SUB_CMD_DISABLE_CACHE);
406f11c7f63SJim Harris       else
407f11c7f63SJim Harris          sati_ata_set_features_construct(ata_io, sequence, ATA_SET_FEATURES_SUB_CMD_ENABLE_CACHE);
408f11c7f63SJim Harris 
409f11c7f63SJim Harris    }
410f11c7f63SJim Harris    else if(sequence->command_specific_data.process_state.ata_command_sent_for_cmp == 1)
411f11c7f63SJim Harris    {
412f11c7f63SJim Harris       // DRA bit is set to 0, enable Read look ahead AAh;
413f11c7f63SJim Harris       // DRA bit is set to 1, disable with set feature command 55h
414f11c7f63SJim Harris       // SCSI_MODE_PAGE_CACHE_PAGE_DRA_BIT== 0x20
415f11c7f63SJim Harris 
416f11c7f63SJim Harris       if ( (current_mode_page[12] & SCSI_MODE_PAGE_CACHE_PAGE_DRA_BIT) == 0)
417f11c7f63SJim Harris          sati_ata_set_features_construct(ata_io, sequence,ATA_SET_FEATURES_SUB_CMD_ENABLE_READ_AHEAD);
418f11c7f63SJim Harris       else
419f11c7f63SJim Harris          sati_ata_set_features_construct(ata_io, sequence,ATA_SET_FEATURES_SUB_CMD_DISABLE_READ_AHEAD);
420f11c7f63SJim Harris 
421f11c7f63SJim Harris       sequence->command_specific_data.process_state.size_of_data_processed += page_size;
422f11c7f63SJim Harris       sequence->command_specific_data.process_state.mode_page_offset += page_size;
423f11c7f63SJim Harris       sequence->command_specific_data.process_state.current_mode_page_processed = TRUE;
424f11c7f63SJim Harris 
425f11c7f63SJim Harris 
426f11c7f63SJim Harris    }
427f11c7f63SJim Harris    // No more ata commands to send
428f11c7f63SJim Harris 
429f11c7f63SJim Harris    sequence->command_specific_data.process_state.ata_command_sent_for_cmp++;
430f11c7f63SJim Harris 
431f11c7f63SJim Harris    status = SATI_SUCCESS;
432f11c7f63SJim Harris 
433f11c7f63SJim Harris    return status;
434f11c7f63SJim Harris }
435f11c7f63SJim Harris 
436f11c7f63SJim Harris /**
437f11c7f63SJim Harris  * @brief This method will check the validity of parameter data of Control mode
438f11c7f63SJim Harris  *            page and further processing the page data if necessary.
439f11c7f63SJim Harris  *
440f11c7f63SJim Harris  * @param[in] mode_select_process_state This parameter points to the processing state fields
441f11c7f63SJim Harris  *            of current mode page.
442f11c7f63SJim Harris  * @param[in] page_size This parameter specifies page size of current mode page.
443f11c7f63SJim Harris  *
444f11c7f63SJim Harris  * @return Indicate if the translation was successful.
445f11c7f63SJim Harris  * @retval SATI_SUCCESS
446f11c7f63SJim Harris  * @retval SATI_COMPLETE
447f11c7f63SJim Harris  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
448f11c7f63SJim Harris  */
449f11c7f63SJim Harris static
sati_mode_select_process_mode_page_control(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io,U32 page_size)450f11c7f63SJim Harris SATI_STATUS sati_mode_select_process_mode_page_control(
451f11c7f63SJim Harris          SATI_TRANSLATOR_SEQUENCE_T* sequence,
452f11c7f63SJim Harris          void     *  scsi_io,
453f11c7f63SJim Harris          void     *  ata_io,
454f11c7f63SJim Harris          U32 page_size
455f11c7f63SJim Harris       )
456f11c7f63SJim Harris {
457f11c7f63SJim Harris    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
458f11c7f63SJim Harris 
459f11c7f63SJim Harris    //SCSI_MODE_PAGE_0A_LENGTH 12
460f11c7f63SJim Harris    U8 current_mode_page[SCSI_MODE_PAGE_0A_LENGTH]={0,0,0,0,0,0,0,0,0,0};
461f11c7f63SJim Harris    U32 mode_page_offset;
462f11c7f63SJim Harris    U32 index;
463f11c7f63SJim Harris 
464f11c7f63SJim Harris    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
465f11c7f63SJim Harris 
466f11c7f63SJim Harris    for(index = 0; index < SCSI_MODE_PAGE_0A_LENGTH; index++)
467f11c7f63SJim Harris    {
468f11c7f63SJim Harris       sati_get_data_byte(sequence, scsi_io, mode_page_offset+index, &current_mode_page[index]);
469f11c7f63SJim Harris    }
470f11c7f63SJim Harris 
471f11c7f63SJim Harris    //bit 1 and 2 of byte3 Qerr full task management model etc. then both bits 0
472f11c7f63SJim Harris    //byte 8 and 9 busy time out period variable if not ffff setable?
473f11c7f63SJim Harris    //check for page data validity
474f11c7f63SJim Harris    //Byte2: 0000???0b  Byte3: Queued Algorithm Modifier should be set to 1 QErr?
475f11c7f63SJim Harris    //Byte4: ??000???   Byte5: ?0???000
476f11c7f63SJim Harris 
477f11c7f63SJim Harris    if (((current_mode_page[0] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK)!= 0) ||
478f11c7f63SJim Harris       (current_mode_page[1] != (SCSI_MODE_PAGE_0A_LENGTH - 2)) ||
479f11c7f63SJim Harris       ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_0A_TST_TMF_RLEC) != 0) ||
480f11c7f63SJim Harris       ((current_mode_page[3] & SCSI_MODE_SELECT_MODE_PAGE_0A_MODIFIER) != 0) ||
481f11c7f63SJim Harris       ((current_mode_page[4] & SCSI_MODE_SELECT_MODE_PAGE_0A_UA_SWP ) != 0) ||
482f11c7f63SJim Harris       ((current_mode_page[5] & SCSI_MODE_SELECT_MODE_PAGE_0A_TAS_AUTO ) != 0 ) )
483f11c7f63SJim Harris    {
484f11c7f63SJim Harris       return SATI_FAILURE_CHECK_RESPONSE_DATA;
485f11c7f63SJim Harris    }
486f11c7f63SJim Harris 
487f11c7f63SJim Harris    if ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_D_SENSE) != 0)
488f11c7f63SJim Harris        sequence->device->descriptor_sense_enable = SCSI_MODE_PAGE_CONTROL_D_SENSE_ENABLE;
489f11c7f63SJim Harris    else
490f11c7f63SJim Harris        sequence->device->descriptor_sense_enable = SCSI_MODE_PAGE_CONTROL_D_SENSE_DISABLE;
491f11c7f63SJim Harris 
492f11c7f63SJim Harris    // no ata command need to be comfirmed
493f11c7f63SJim Harris    {
494f11c7f63SJim Harris       sequence->command_specific_data.process_state.size_of_data_processed += page_size;
495f11c7f63SJim Harris       sequence->command_specific_data.process_state.mode_page_offset += page_size;
496f11c7f63SJim Harris       sequence->command_specific_data.process_state.current_mode_page_processed = TRUE;
497f11c7f63SJim Harris    }
498f11c7f63SJim Harris 
499f11c7f63SJim Harris    status = SATI_COMPLETE;
500f11c7f63SJim Harris 
501f11c7f63SJim Harris    return status;
502f11c7f63SJim Harris }
503f11c7f63SJim Harris 
504f11c7f63SJim Harris /**
505f11c7f63SJim Harris  * @brief This method will check the validity of parameter data of Information Exception Control
506f11c7f63SJim Harris  *            mode page and further processing the page data if necessary.
507f11c7f63SJim Harris  *
508f11c7f63SJim Harris  * @param[in] page_size This parameter specifies page size of current mode page.
509f11c7f63SJim Harris  *
510f11c7f63SJim Harris  * @return Indicate if the translation was successful.
511f11c7f63SJim Harris  * @retval SATI_SUCCESS
512f11c7f63SJim Harris  * @retval SATI_COMPLETE
513f11c7f63SJim Harris  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
514f11c7f63SJim Harris  */
515f11c7f63SJim Harris static
sati_mode_select_process_mode_page_informational_exception_control(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io,U32 page_size)516f11c7f63SJim Harris SATI_STATUS sati_mode_select_process_mode_page_informational_exception_control(
517f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
518f11c7f63SJim Harris    void     *  scsi_io,
519f11c7f63SJim Harris    void     *  ata_io,
520f11c7f63SJim Harris    U32 page_size
521f11c7f63SJim Harris    )
522f11c7f63SJim Harris {
523f11c7f63SJim Harris    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
524f11c7f63SJim Harris 
525f11c7f63SJim Harris    //SCSI_MODE_PAGE_1C_LENGTH 12
526f11c7f63SJim Harris    U8 current_mode_page[SCSI_MODE_PAGE_1C_LENGTH]={0,0,0,0,0,0,0,0,0,0,0,0};
527f11c7f63SJim Harris    U32 mode_page_offset;
528f11c7f63SJim Harris    U32 index;
529f11c7f63SJim Harris 
530f11c7f63SJim Harris    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
531f11c7f63SJim Harris    sequence->type = SATI_SEQUENCE_MODE_SELECT_MODE_INFORMATION_EXCEPT_CONTROL;
532f11c7f63SJim Harris 
533f11c7f63SJim Harris    for(index = 0; index < 4; index++)
534f11c7f63SJim Harris    {
535f11c7f63SJim Harris       sati_get_data_byte(sequence, scsi_io, mode_page_offset+index, &current_mode_page[index]);
536f11c7f63SJim Harris    }
537f11c7f63SJim Harris 
538f11c7f63SJim Harris    //Check for data validity
539f11c7f63SJim Harris    //SPF(0b); Page length 0x0A; Byte2 0????0?? Byte3: ????1100
540f11c7f63SJim Harris    //SCSI_MODE_SELECT_MODE_PAGE_MRIE_BYTE same as REPORT_INFO_EXCEPTION_CONDITION_ON_REQUEST 0x6
541f11c7f63SJim Harris    //SCSI_MODE_PAGE_DEXCPT_ENABLE
542f11c7f63SJim Harris 
543f11c7f63SJim Harris    if (((current_mode_page[0] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK)!= 0) ||
544f11c7f63SJim Harris       (current_mode_page[1] != (SCSI_MODE_PAGE_1C_LENGTH - 2)) ||
545f11c7f63SJim Harris       ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_1C_PERF_TEST)!= 0 ) ||
546f11c7f63SJim Harris       ((current_mode_page[3] & SCSI_MODE_SELECT_MODE_PAGE_MRIE_MASK) !=
547f11c7f63SJim Harris       SCSI_MODE_SELECT_MODE_PAGE_MRIE_BYTE ))
548f11c7f63SJim Harris    {
549f11c7f63SJim Harris       return SATI_FAILURE_CHECK_RESPONSE_DATA;
550f11c7f63SJim Harris    }
551f11c7f63SJim Harris 
552f11c7f63SJim Harris    // DEXCPT bit is set to 0, enable SMART reporting D8h;
553f11c7f63SJim Harris    // DEXCPT bit is set to 1, disable SMART reporting D9h
554f11c7f63SJim Harris    // SCSI_MODE_PAGE_DEXCPT_ENABLE== 0x08
555f11c7f63SJim Harris 
556f11c7f63SJim Harris    if ( (current_mode_page[2] & SCSI_MODE_PAGE_DEXCPT_ENABLE) == 0)
557f11c7f63SJim Harris       sati_ata_smart_return_status_construct(ata_io, sequence, ATA_SMART_SUB_CMD_ENABLE);
558f11c7f63SJim Harris    else
559f11c7f63SJim Harris       sati_ata_smart_return_status_construct(ata_io, sequence, ATA_SMART_SUB_CMD_DISABLE);
560f11c7f63SJim Harris 
561f11c7f63SJim Harris    sequence->command_specific_data.process_state.size_of_data_processed += page_size;
562f11c7f63SJim Harris    sequence->command_specific_data.process_state.mode_page_offset += page_size;
563f11c7f63SJim Harris    sequence->command_specific_data.process_state.current_mode_page_processed = TRUE;
564f11c7f63SJim Harris    // No more ata commands to send
565f11c7f63SJim Harris 
566f11c7f63SJim Harris    status = SATI_SUCCESS;
567f11c7f63SJim Harris 
568f11c7f63SJim Harris    return status;
569f11c7f63SJim Harris }
570f11c7f63SJim Harris 
571f11c7f63SJim Harris /**
572f11c7f63SJim Harris  * @brief This method will check the validity of parameter data of Power Condition mode
573f11c7f63SJim Harris  *            page and issue multiple ATA set feature commands to complete the translation.
574f11c7f63SJim Harris  *
575f11c7f63SJim Harris  * @param[in] mode_select_process_state This parameter points to the processing state fields
576f11c7f63SJim Harris  *            of current mode page.
577f11c7f63SJim Harris  * @param[in] page_size This parameter specifies page size of current mode page.
578f11c7f63SJim Harris  *
579f11c7f63SJim Harris  * @return Indicate if the translation was successful.
580f11c7f63SJim Harris  * @retval SATI_SUCCESS
581f11c7f63SJim Harris  * @retval SATI_COMPLETE
582f11c7f63SJim Harris  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
583f11c7f63SJim Harris  */
584f11c7f63SJim Harris static
sati_mode_select_process_mode_page_power_condition(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io,U32 page_size)585f11c7f63SJim Harris SATI_STATUS sati_mode_select_process_mode_page_power_condition(
586f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
587f11c7f63SJim Harris    void * scsi_io,
588f11c7f63SJim Harris    void * ata_io,
589f11c7f63SJim Harris    U32 page_size
590f11c7f63SJim Harris    )
591f11c7f63SJim Harris {
592f11c7f63SJim Harris    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
593f11c7f63SJim Harris 
594f11c7f63SJim Harris    //SCSI_MODE_PAGE_1A_LENGTH 10
595f11c7f63SJim Harris    U8 current_mode_page[SCSI_MODE_PAGE_1A_LENGTH] = {0,0,0,0,0,0,0,0,0,0};
596f11c7f63SJim Harris    U32 mode_page_offset;
597f11c7f63SJim Harris    U32 index;
598f11c7f63SJim Harris 
599f11c7f63SJim Harris    U32 timer = 0;
600f11c7f63SJim Harris    U16 count = 0;
601f11c7f63SJim Harris 
602f11c7f63SJim Harris    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
603f11c7f63SJim Harris 
604f11c7f63SJim Harris    sequence->type = SATI_SEQUENCE_MODE_SELECT_MODE_POWER_CONDITION;
605f11c7f63SJim Harris 
606f11c7f63SJim Harris    for(index = 0; index < SCSI_MODE_PAGE_1A_LENGTH; index++)
607f11c7f63SJim Harris    {
608f11c7f63SJim Harris       sati_get_data_byte(sequence, scsi_io, mode_page_offset+index, &current_mode_page[index]);
609f11c7f63SJim Harris    }
610f11c7f63SJim Harris 
611f11c7f63SJim Harris    //Check for data validity
612f11c7f63SJim Harris    //SPF(0b); Page length 0x0A;
613f11c7f63SJim Harris 
614f11c7f63SJim Harris    if (((current_mode_page[0] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK)!= 0) ||
615f11c7f63SJim Harris       (current_mode_page[1] != (SCSI_MODE_PAGE_1A_LENGTH - 2) ) ||
616f11c7f63SJim Harris       ((current_mode_page[3] & SCSI_MODE_PAGE_POWER_CONDITION_IDLE)!= 0)
617f11c7f63SJim Harris       )
618f11c7f63SJim Harris    {
619f11c7f63SJim Harris       //parameter data passed in containing data that doesn't meet the SAT-2 requirement
620f11c7f63SJim Harris       return SATI_FAILURE_CHECK_RESPONSE_DATA;
621f11c7f63SJim Harris    }
622f11c7f63SJim Harris 
623f11c7f63SJim Harris    // STANDBY bit is set to 0, do nothing since the standby timer can't be set;
624f11c7f63SJim Harris    // STANDBY bit is set to 1, translate the standby timer
625f11c7f63SJim Harris    // SCSI_MODE_PAGE_POWER_CONDITION_STANDBY== 0x01
626f11c7f63SJim Harris    if (current_mode_page[3] & SCSI_MODE_PAGE_POWER_CONDITION_STANDBY)
627f11c7f63SJim Harris    {
628f11c7f63SJim Harris       timer = (current_mode_page[8]<<24) + (current_mode_page[9]<<16) + (current_mode_page[10]<<8) + current_mode_page[11];
629f11c7f63SJim Harris 
630f11c7f63SJim Harris       //If the ATA IDENTIFY DEVICE data word 49, bit 13 is set to one,
631f11c7f63SJim Harris       if (sequence->device->capabilities & SATI_DEVICE_CAP_STANDBY_ENABLE)
632f11c7f63SJim Harris       {
633f11c7f63SJim Harris          if (timer == 0)
634f11c7f63SJim Harris          {
635f11c7f63SJim Harris             //TPV=0 send ATA STANDBY_IMMEDIATE
636f11c7f63SJim Harris             sati_ata_standby_immediate_construct(ata_io, sequence);
637f11c7f63SJim Harris             sequence->command_specific_data.translated_command = ATA_STANDBY_IMMED;
638f11c7f63SJim Harris          }
639f11c7f63SJim Harris          else if ((timer > 0) && (timer <= 12000))
640f11c7f63SJim Harris          {
641f11c7f63SJim Harris             //1 to 12 000 INT((z - 1) / 50) + 1
642f11c7f63SJim Harris             count = (U16)((timer -1) / 50) + 1;
643f11c7f63SJim Harris             sati_ata_standby_construct(ata_io, sequence, count);
644f11c7f63SJim Harris          }
645f11c7f63SJim Harris          else if ((timer > 12000) && (timer <= 12600))
646f11c7f63SJim Harris          {
647f11c7f63SJim Harris             //12 001 to 12 600 FCh
648f11c7f63SJim Harris             sati_ata_standby_construct(ata_io, sequence, 0xFC);
649f11c7f63SJim Harris          }
650f11c7f63SJim Harris          else if ((timer > 12600) && (timer <= 12750))
651f11c7f63SJim Harris          {
652f11c7f63SJim Harris             //12 601 to 12 750 FFh
653f11c7f63SJim Harris             sati_ata_standby_construct(ata_io, sequence, 0xFF);
654f11c7f63SJim Harris          }
655f11c7f63SJim Harris          else if ((timer > 12750) && (timer < 18000))
656f11c7f63SJim Harris          {
657f11c7f63SJim Harris             //12 751 to 17 999 F1h
658f11c7f63SJim Harris             sati_ata_standby_construct(ata_io, sequence, 0xF1);
659f11c7f63SJim Harris          }
660f11c7f63SJim Harris          else if ((timer >= 18000) && (timer <= 198000))
661f11c7f63SJim Harris          {
662f11c7f63SJim Harris             //18 000 to 198 000 INT(z / 18 000) + 240
663f11c7f63SJim Harris             count = (U16)(timer / 18000) + 240;
664f11c7f63SJim Harris             sati_ata_standby_construct(ata_io, sequence, count);
665f11c7f63SJim Harris          }
666f11c7f63SJim Harris          else
667f11c7f63SJim Harris          {
668f11c7f63SJim Harris             //All other values FDh
669f11c7f63SJim Harris             sati_ata_standby_construct(ata_io, sequence, 0xFD);
670f11c7f63SJim Harris          }
671f11c7f63SJim Harris          status = SATI_SUCCESS ;
672f11c7f63SJim Harris       }
673f11c7f63SJim Harris       else
674f11c7f63SJim Harris       {
675f11c7f63SJim Harris          status = SATI_FAILURE_CHECK_RESPONSE_DATA;
676f11c7f63SJim Harris          //If the ATA IDENTIFY DEVICE data word 49, bit 13 is set to 0
677f11c7f63SJim Harris       }
678f11c7f63SJim Harris    }
679f11c7f63SJim Harris    else
680f11c7f63SJim Harris    {
681f11c7f63SJim Harris       status = SATI_COMPLETE;
682f11c7f63SJim Harris    }
683f11c7f63SJim Harris 
684f11c7f63SJim Harris    sequence->command_specific_data.process_state.size_of_data_processed += page_size;
685f11c7f63SJim Harris    sequence->command_specific_data.process_state.mode_page_offset += page_size;
686f11c7f63SJim Harris    sequence->command_specific_data.process_state.current_mode_page_processed = TRUE;
687f11c7f63SJim Harris 
688f11c7f63SJim Harris    return status;
689f11c7f63SJim Harris }
690f11c7f63SJim Harris 
691f11c7f63SJim Harris /**
692f11c7f63SJim Harris  * @brief This method will process the mode page.
693f11c7f63SJim Harris  *
694f11c7f63SJim Harris  *
695f11c7f63SJim Harris  * @return Indicate if the translation was successful.
696f11c7f63SJim Harris  * @retval SATI_SUCCESS
697f11c7f63SJim Harris  * @retval SATI_COMPLETE
698f11c7f63SJim Harris  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
699f11c7f63SJim Harris  */
700f11c7f63SJim Harris static
sati_mode_select_process_mode_page(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io)701f11c7f63SJim Harris SATI_STATUS sati_mode_select_process_mode_page(
702f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T* sequence,
703f11c7f63SJim Harris    void                      * scsi_io,
704f11c7f63SJim Harris    void                      * ata_io
705f11c7f63SJim Harris )
706f11c7f63SJim Harris {
707f11c7f63SJim Harris    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
708f11c7f63SJim Harris 
709f11c7f63SJim Harris    U8 page_code;
710f11c7f63SJim Harris    U32 page_size = 0; // in bytes
711f11c7f63SJim Harris    U32 size_of_data_to_be_processed;
712f11c7f63SJim Harris 
713f11c7f63SJim Harris    U8 page_code_byte;
714f11c7f63SJim Harris    U32 mode_page_offset;
715f11c7f63SJim Harris 
716f11c7f63SJim Harris    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
717f11c7f63SJim Harris 
718f11c7f63SJim Harris    sati_get_data_byte(sequence, scsi_io, mode_page_offset, &page_code_byte);
719f11c7f63SJim Harris 
720f11c7f63SJim Harris    // No more pages.
721f11c7f63SJim Harris    if(sequence->command_specific_data.process_state.mode_pages_size >
722f11c7f63SJim Harris       sequence->command_specific_data.process_state.size_of_data_processed)
723f11c7f63SJim Harris    {
724f11c7f63SJim Harris       //SCSI_MODE_SENSE_PAGE_CODE_ENABLE==0x3f same for Mode Select
725f11c7f63SJim Harris       page_code = page_code_byte & SCSI_MODE_SENSE_PAGE_CODE_ENABLE;
726f11c7f63SJim Harris       page_size = sati_mode_select_get_mode_page_size(page_code);
727f11c7f63SJim Harris       size_of_data_to_be_processed = sequence->command_specific_data.process_state.mode_pages_size
728f11c7f63SJim Harris          - sequence->command_specific_data.process_state.size_of_data_processed;
729f11c7f63SJim Harris 
730f11c7f63SJim Harris       if( page_size == 0 )
731f11c7f63SJim Harris       {
732f11c7f63SJim Harris          status = SATI_FAILURE_CHECK_RESPONSE_DATA;
733f11c7f63SJim Harris       }
734f11c7f63SJim Harris       else
735f11c7f63SJim Harris       {
736f11c7f63SJim Harris          // process mode page
737f11c7f63SJim Harris          switch(page_code)
738f11c7f63SJim Harris          {
739f11c7f63SJim Harris          case SCSI_MODE_PAGE_READ_WRITE_ERROR:
740f11c7f63SJim Harris             status = sati_mode_select_process_mode_page_read_write_error_recovery(
741f11c7f63SJim Harris                         sequence,
742f11c7f63SJim Harris                         scsi_io,
743f11c7f63SJim Harris                         page_size
744f11c7f63SJim Harris                      );
745f11c7f63SJim Harris             break;
746f11c7f63SJim Harris 
747f11c7f63SJim Harris          case SCSI_MODE_PAGE_DISCONNECT_RECONNECT:
748f11c7f63SJim Harris             status = sati_mode_select_process_mode_page_disconnect_reconnect(
749f11c7f63SJim Harris                         &sequence->command_specific_data.process_state,
750f11c7f63SJim Harris                         page_size
751f11c7f63SJim Harris                      );
752f11c7f63SJim Harris             break;
753f11c7f63SJim Harris 
754f11c7f63SJim Harris          case SCSI_MODE_PAGE_CACHING:
755f11c7f63SJim Harris             status = sati_mode_select_process_mode_page_caching(
756f11c7f63SJim Harris                         sequence,
757f11c7f63SJim Harris                         scsi_io,
758f11c7f63SJim Harris                         ata_io,
759f11c7f63SJim Harris                         page_size
760f11c7f63SJim Harris                      );
761f11c7f63SJim Harris             break;
762f11c7f63SJim Harris 
763f11c7f63SJim Harris          case SCSI_MODE_PAGE_CONTROL:
764f11c7f63SJim Harris             status = sati_mode_select_process_mode_page_control(
765f11c7f63SJim Harris                         sequence,
766f11c7f63SJim Harris                         scsi_io,
767f11c7f63SJim Harris                         ata_io,
768f11c7f63SJim Harris                         page_size
769f11c7f63SJim Harris                      );
770f11c7f63SJim Harris             break;
771f11c7f63SJim Harris 
772f11c7f63SJim Harris          case SCSI_MODE_PAGE_INFORMATIONAL_EXCP_CONTROL:
773f11c7f63SJim Harris             status = sati_mode_select_process_mode_page_informational_exception_control(
774f11c7f63SJim Harris                         sequence,
775f11c7f63SJim Harris                         scsi_io,
776f11c7f63SJim Harris                         ata_io,
777f11c7f63SJim Harris                         page_size
778f11c7f63SJim Harris                      );
779f11c7f63SJim Harris             break;
780f11c7f63SJim Harris 
781f11c7f63SJim Harris          case SCSI_MODE_PAGE_POWER_CONDITION:
782f11c7f63SJim Harris             status = sati_mode_select_process_mode_page_power_condition(
783f11c7f63SJim Harris                         sequence,
784f11c7f63SJim Harris                         scsi_io,
785f11c7f63SJim Harris                         ata_io,
786f11c7f63SJim Harris                         page_size
787f11c7f63SJim Harris                      );
788f11c7f63SJim Harris 
789f11c7f63SJim Harris             break;
790f11c7f63SJim Harris 
791f11c7f63SJim Harris          default:
792f11c7f63SJim Harris             break;
793f11c7f63SJim Harris          }
794f11c7f63SJim Harris 
795f11c7f63SJim Harris       }
796f11c7f63SJim Harris    }
797f11c7f63SJim Harris 
798f11c7f63SJim Harris    return status;
799f11c7f63SJim Harris }
800f11c7f63SJim Harris 
801f11c7f63SJim Harris //******************************************************************************
802f11c7f63SJim Harris //* P U B L I C   M E T H O D S
803f11c7f63SJim Harris //******************************************************************************
804f11c7f63SJim Harris 
805f11c7f63SJim Harris /**
806f11c7f63SJim Harris  * @brief This method will translate the SCSI Mode Select 6 byte or 10 byte command
807f11c7f63SJim Harris  *        into corresponding ATA commands.  Depending upon the capabilities
808f11c7f63SJim Harris  *        supported by the target different ATA commands can be selected.
809f11c7f63SJim Harris  *        Additionally, in some cases more than a single ATA command may
810f11c7f63SJim Harris  *        be required.
811f11c7f63SJim Harris  *
812f11c7f63SJim Harris  * @return Indicate if the command translation succeeded.
813f11c7f63SJim Harris  * @retval SCI_SUCCESS This is returned if the command translation was
814f11c7f63SJim Harris  *         successful.
815f11c7f63SJim Harris  * @retval SCI_COMPLETE This is returned if the command translation was
816f11c7f63SJim Harris  *         successful and no ATA commands need to be set.
817f11c7f63SJim Harris  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
818f11c7f63SJim Harris  *         sense data has been created as a result of something specified
819f11c7f63SJim Harris  *         in the parameter data fields.
820f11c7f63SJim Harris  */
821f11c7f63SJim Harris static
sati_mode_select_translate_command(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io,U32 cdb_size)822f11c7f63SJim Harris SATI_STATUS sati_mode_select_translate_command(
823f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T   * sequence,
824f11c7f63SJim Harris    void                         * scsi_io,
825f11c7f63SJim Harris    void                         * ata_io,
826f11c7f63SJim Harris    U32                          cdb_size
827f11c7f63SJim Harris )
828f11c7f63SJim Harris {
829f11c7f63SJim Harris    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
830f11c7f63SJim Harris    U32 mode_page_offset;
831f11c7f63SJim Harris    U32 block_descriptor_length;
832f11c7f63SJim Harris    U32 index;
833f11c7f63SJim Harris    U16 data_transfer_length;
834f11c7f63SJim Harris    U8 current_mode_parameters[8]={0,0,0,0,0,0,0,0};
835f11c7f63SJim Harris    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
836f11c7f63SJim Harris 
837f11c7f63SJim Harris    // cdb_size must be 6 or 10
838f11c7f63SJim Harris    if(FALSE == (cdb_size == 6 || cdb_size == 10))
839f11c7f63SJim Harris    {
840f11c7f63SJim Harris       return status;
841f11c7f63SJim Harris    }
842f11c7f63SJim Harris 
843f11c7f63SJim Harris    if(sequence->state == SATI_SEQUENCE_STATE_INITIAL)
844f11c7f63SJim Harris    {
845f11c7f63SJim Harris       sequence->command_specific_data.process_state.ata_command_sent_for_cmp = 0;
846f11c7f63SJim Harris       sequence->state = SATI_SEQUENCE_STATE_TRANSLATE_DATA;
847f11c7f63SJim Harris    }
848f11c7f63SJim Harris 
849f11c7f63SJim Harris    //First, initializes mode_sel_processing_state
850f11c7f63SJim Harris    if ( sequence->command_specific_data.process_state.ata_command_sent_for_cmp == 0 )
851f11c7f63SJim Harris    {
852f11c7f63SJim Harris       if (cdb_size == 6)
853f11c7f63SJim Harris       {
854f11c7f63SJim Harris          //CDB byte 4 is the parameter length
855f11c7f63SJim Harris          data_transfer_length = sati_get_cdb_byte(cdb, 4);
856f11c7f63SJim Harris       }
857f11c7f63SJim Harris       else
858f11c7f63SJim Harris       {
859f11c7f63SJim Harris          //CDB byte 7 and 8 for Mode Select 10
860f11c7f63SJim Harris          data_transfer_length = (sati_get_cdb_byte(cdb, 7) << 8) + sati_get_cdb_byte(cdb, 8);
861f11c7f63SJim Harris       }
862f11c7f63SJim Harris 
863f11c7f63SJim Harris       sequence->allocation_length = data_transfer_length;
864f11c7f63SJim Harris 
865f11c7f63SJim Harris       //Get 8 bytes for headers (4 bytes for Mode Select 6 and 8 bytes for Mode Select 10)
866f11c7f63SJim Harris       for( index = 0; index < 8; index++ )
867f11c7f63SJim Harris       {
868f11c7f63SJim Harris          sati_get_data_byte(sequence, scsi_io, index, &current_mode_parameters[index]);
869f11c7f63SJim Harris       }
870f11c7f63SJim Harris 
871f11c7f63SJim Harris       //medium type should be 0
872f11c7f63SJim Harris       if ( sati_mode_select_get_medium_type(current_mode_parameters, cdb_size) != 0 )
873f11c7f63SJim Harris       {
874f11c7f63SJim Harris          sati_scsi_sense_data_construct(
875f11c7f63SJim Harris             sequence,
876f11c7f63SJim Harris             scsi_io,
877f11c7f63SJim Harris             SCSI_STATUS_CHECK_CONDITION,
878f11c7f63SJim Harris             SCSI_SENSE_ILLEGAL_REQUEST,
879f11c7f63SJim Harris             SCSI_ASC_INVALID_FIELD_IN_PARM_LIST,
880f11c7f63SJim Harris             SCSI_ASCQ_INVALID_FIELD_IN_PARM_LIST
881f11c7f63SJim Harris          );
882f11c7f63SJim Harris          return status;
883f11c7f63SJim Harris       }
884f11c7f63SJim Harris 
885f11c7f63SJim Harris       block_descriptor_length = sati_mode_select_get_mode_block_descriptor_length(
886f11c7f63SJim Harris                                    current_mode_parameters,
887f11c7f63SJim Harris                                    cdb_size
888f11c7f63SJim Harris                                 );
889f11c7f63SJim Harris 
890f11c7f63SJim Harris       mode_page_offset = sati_mode_select_get_mode_page_offset(
891f11c7f63SJim Harris                             block_descriptor_length,
892f11c7f63SJim Harris                             cdb_size
893f11c7f63SJim Harris                          );
894f11c7f63SJim Harris 
895f11c7f63SJim Harris       if(mode_page_offset > data_transfer_length)
896f11c7f63SJim Harris       {
897f11c7f63SJim Harris          sequence->state = SATI_SEQUENCE_STATE_FINAL;
898f11c7f63SJim Harris          status = SATI_FAILURE_CHECK_RESPONSE_DATA;
899f11c7f63SJim Harris       }
900f11c7f63SJim Harris       else
901f11c7f63SJim Harris       {
902f11c7f63SJim Harris          sati_mode_select_initialize_mode_sel_processing_state(
903f11c7f63SJim Harris             sequence,
904f11c7f63SJim Harris             scsi_io,
905f11c7f63SJim Harris             ata_io,
906f11c7f63SJim Harris             data_transfer_length,
907f11c7f63SJim Harris             mode_page_offset
908f11c7f63SJim Harris          );
909f11c7f63SJim Harris 
910f11c7f63SJim Harris       }
911f11c7f63SJim Harris     }
912f11c7f63SJim Harris 
913f11c7f63SJim Harris    // move to next mode page
914f11c7f63SJim Harris    if(sequence->command_specific_data.process_state.current_mode_page_processed)
915f11c7f63SJim Harris    {
916f11c7f63SJim Harris       sequence->command_specific_data.process_state.ata_command_sent_for_cmp = 0;
917f11c7f63SJim Harris       sequence->command_specific_data.process_state.current_mode_page_processed = FALSE;
918f11c7f63SJim Harris    }
919f11c7f63SJim Harris 
920f11c7f63SJim Harris    status = sati_mode_select_process_mode_page(sequence, scsi_io, ata_io);
921f11c7f63SJim Harris 
922f11c7f63SJim Harris    if(sequence->command_specific_data.process_state.current_mode_page_processed != FALSE)
923f11c7f63SJim Harris    {
924f11c7f63SJim Harris       // Done this page
925f11c7f63SJim Harris       sequence->state = SATI_SEQUENCE_STATE_FINAL;
926f11c7f63SJim Harris    }
927f11c7f63SJim Harris    else
928f11c7f63SJim Harris    {
929f11c7f63SJim Harris       sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE;
930f11c7f63SJim Harris    }
931f11c7f63SJim Harris 
932f11c7f63SJim Harris    if(status == SATI_FAILURE_CHECK_RESPONSE_DATA)
933f11c7f63SJim Harris    {
934f11c7f63SJim Harris       sequence->state = SATI_SEQUENCE_STATE_FINAL;
935f11c7f63SJim Harris       sati_scsi_sense_data_construct(
936f11c7f63SJim Harris          sequence,
937f11c7f63SJim Harris          scsi_io,
938f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
939f11c7f63SJim Harris          SCSI_SENSE_ILLEGAL_REQUEST,
940f11c7f63SJim Harris          SCSI_ASC_INVALID_FIELD_IN_PARM_LIST,
941f11c7f63SJim Harris          SCSI_ASCQ_INVALID_FIELD_IN_PARM_LIST
942f11c7f63SJim Harris       );
943f11c7f63SJim Harris    }
944f11c7f63SJim Harris 
945f11c7f63SJim Harris    return status;
946f11c7f63SJim Harris }
947f11c7f63SJim Harris 
948f11c7f63SJim Harris /**
949f11c7f63SJim Harris  * @brief This method will call Mode Select 6 Translation command
950f11c7f63SJim Harris  *        For more information on the parameters passed to this method,
951f11c7f63SJim Harris  *        please reference sati_translate_command().
952f11c7f63SJim Harris  *
953f11c7f63SJim Harris  * @return Indicate if the command translation succeeded.
954f11c7f63SJim Harris  * @retval SCI_SUCCESS This is returned if the command translation was
955f11c7f63SJim Harris  *         successful.
956f11c7f63SJim Harris  * @retval SCI_COMPLETE This is returned if the command translation was
957f11c7f63SJim Harris  *         successful and no ATA commands need to be set.
958f11c7f63SJim Harris  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
959f11c7f63SJim Harris  *         sense data has been created as a result of something specified
960f11c7f63SJim Harris  *         in the parameter data fields.
961f11c7f63SJim Harris  */
sati_mode_select_6_translate_command(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io)962f11c7f63SJim Harris SATI_STATUS sati_mode_select_6_translate_command(
963f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
964f11c7f63SJim Harris    void                       * scsi_io,
965f11c7f63SJim Harris    void                       * ata_io
966f11c7f63SJim Harris )
967f11c7f63SJim Harris {
968f11c7f63SJim Harris    SATI_STATUS status=SATI_FAILURE;
969f11c7f63SJim Harris    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
970f11c7f63SJim Harris 
971f11c7f63SJim Harris    //PF bit needs to be 1 byte1 bit ???1????
972f11c7f63SJim Harris    if ((sati_get_cdb_byte(cdb, 1) & SCSI_MODE_SELECT_PF_MASK) == !SCSI_MODE_SELECT_PF_BIT)
973f11c7f63SJim Harris    {
974f11c7f63SJim Harris       sati_scsi_sense_data_construct(
975f11c7f63SJim Harris          sequence,
976f11c7f63SJim Harris          scsi_io,
977f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
978f11c7f63SJim Harris          SCSI_SENSE_ILLEGAL_REQUEST,
979f11c7f63SJim Harris          SCSI_ASC_INVALID_FIELD_IN_CDB,
980f11c7f63SJim Harris          SCSI_ASCQ_INVALID_FIELD_IN_CDB
981f11c7f63SJim Harris       );
982f11c7f63SJim Harris       status = SATI_FAILURE_CHECK_RESPONSE_DATA;
983f11c7f63SJim Harris       return status;
984f11c7f63SJim Harris    }
985f11c7f63SJim Harris 
986f11c7f63SJim Harris    status=sati_mode_select_translate_command(
987f11c7f63SJim Harris              sequence,
988f11c7f63SJim Harris              scsi_io,
989f11c7f63SJim Harris              ata_io,
990f11c7f63SJim Harris              6
991f11c7f63SJim Harris           );
992f11c7f63SJim Harris 
993f11c7f63SJim Harris    if(status == SATI_FAILURE_CHECK_RESPONSE_DATA)
994f11c7f63SJim Harris    {
995f11c7f63SJim Harris       sati_scsi_sense_data_construct(
996f11c7f63SJim Harris          sequence,
997f11c7f63SJim Harris          scsi_io,
998f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
999f11c7f63SJim Harris          SCSI_SENSE_ILLEGAL_REQUEST,
1000f11c7f63SJim Harris          SCSI_ASC_INVALID_FIELD_IN_PARM_LIST,
1001f11c7f63SJim Harris          SCSI_ASCQ_INVALID_FIELD_IN_PARM_LIST
1002f11c7f63SJim Harris       );
1003f11c7f63SJim Harris    }
1004f11c7f63SJim Harris    return status;
1005f11c7f63SJim Harris 
1006f11c7f63SJim Harris }
1007f11c7f63SJim Harris 
1008f11c7f63SJim Harris /**
1009f11c7f63SJim Harris  * @brief This method will call Mode Select 10 translation command
1010f11c7f63SJim Harris  *        For more information on the parameters passed to this method,
1011f11c7f63SJim Harris  *        please reference sati_translate_command().
1012f11c7f63SJim Harris  *
1013f11c7f63SJim Harris  * @return Indicate if the command translation succeeded.
1014f11c7f63SJim Harris  * @retval SCI_SUCCESS This is returned if the command translation was
1015f11c7f63SJim Harris  *         successful.
1016f11c7f63SJim Harris  * @retval SCI_COMPLETE This is returned if the command translation was
1017f11c7f63SJim Harris  *         successful and no ATA commands need to be set.
1018f11c7f63SJim Harris  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
1019f11c7f63SJim Harris  *         sense data has been created as a result of something specified
1020f11c7f63SJim Harris  *         in the parameter data fields.
1021f11c7f63SJim Harris  */
sati_mode_select_10_translate_command(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io)1022f11c7f63SJim Harris SATI_STATUS sati_mode_select_10_translate_command(
1023f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1024f11c7f63SJim Harris    void                       * scsi_io,
1025f11c7f63SJim Harris    void                       * ata_io
1026f11c7f63SJim Harris )
1027f11c7f63SJim Harris {
1028f11c7f63SJim Harris    SATI_STATUS status=SATI_FAILURE;
1029f11c7f63SJim Harris    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
1030f11c7f63SJim Harris 
1031f11c7f63SJim Harris    //PF bit needs to be 1 byte1 bit ???1????
1032f11c7f63SJim Harris    if ((sati_get_cdb_byte(cdb, 1) & SCSI_MODE_SELECT_PF_MASK) == !SCSI_MODE_SELECT_PF_BIT)
1033f11c7f63SJim Harris    {
1034f11c7f63SJim Harris       sati_scsi_sense_data_construct(
1035f11c7f63SJim Harris          sequence,
1036f11c7f63SJim Harris          scsi_io,
1037f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
1038f11c7f63SJim Harris          SCSI_SENSE_ILLEGAL_REQUEST,
1039f11c7f63SJim Harris          SCSI_ASC_INVALID_FIELD_IN_CDB,
1040f11c7f63SJim Harris          SCSI_ASCQ_INVALID_FIELD_IN_CDB
1041f11c7f63SJim Harris       );
1042f11c7f63SJim Harris       status = SATI_FAILURE_CHECK_RESPONSE_DATA;
1043f11c7f63SJim Harris       return status;
1044f11c7f63SJim Harris    }
1045f11c7f63SJim Harris 
1046f11c7f63SJim Harris    status=sati_mode_select_translate_command(
1047f11c7f63SJim Harris              sequence,
1048f11c7f63SJim Harris              scsi_io,
1049f11c7f63SJim Harris              ata_io,
1050f11c7f63SJim Harris              10
1051f11c7f63SJim Harris           );
1052f11c7f63SJim Harris 
1053f11c7f63SJim Harris    if(status == SATI_FAILURE_CHECK_RESPONSE_DATA)
1054f11c7f63SJim Harris    {
1055f11c7f63SJim Harris       sati_scsi_sense_data_construct(
1056f11c7f63SJim Harris          sequence,
1057f11c7f63SJim Harris          scsi_io,
1058f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
1059f11c7f63SJim Harris          SCSI_SENSE_ILLEGAL_REQUEST,
1060f11c7f63SJim Harris          SCSI_ASC_INVALID_FIELD_IN_PARM_LIST,
1061f11c7f63SJim Harris          SCSI_ASCQ_INVALID_FIELD_IN_PARM_LIST
1062f11c7f63SJim Harris       );
1063f11c7f63SJim Harris    }
1064f11c7f63SJim Harris    return status;
1065f11c7f63SJim Harris }
1066f11c7f63SJim Harris 
1067f11c7f63SJim Harris /**
1068f11c7f63SJim Harris * @brief This method will conduct error handling for the ATA Set Features command
1069f11c7f63SJim Harris *        that is issued during a Mode Select translation for the Caching Mode
1070f11c7f63SJim Harris *        page.
1071f11c7f63SJim Harris *
1072f11c7f63SJim Harris *
1073f11c7f63SJim Harris * @return Indicate if the command translation succeeded.
1074f11c7f63SJim Harris *
1075f11c7f63SJim Harris * @retval SCI_COMPLETE This is returned if the command translation was
1076f11c7f63SJim Harris *         successful and no additional ATA commands need to be set.
1077f11c7f63SJim Harris * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
1078f11c7f63SJim Harris *         sense data has been created as a result of an error returned
1079f11c7f63SJim Harris */
sati_mode_select_translate_response(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io)1080f11c7f63SJim Harris SATI_STATUS sati_mode_select_translate_response(
1081f11c7f63SJim Harris SATI_TRANSLATOR_SEQUENCE_T * sequence,
1082f11c7f63SJim Harris void                       * scsi_io,
1083f11c7f63SJim Harris void                       * ata_io
1084f11c7f63SJim Harris )
1085f11c7f63SJim Harris {
1086f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
1087f11c7f63SJim Harris    SATI_STATUS status = SATI_FAILURE;
1088f11c7f63SJim Harris 
1089f11c7f63SJim Harris    if(sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT)
1090f11c7f63SJim Harris    {
1091f11c7f63SJim Harris       sati_scsi_sense_data_construct(
1092f11c7f63SJim Harris          sequence,
1093f11c7f63SJim Harris          scsi_io,
1094f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
1095f11c7f63SJim Harris          SCSI_SENSE_ABORTED_COMMAND,
1096f11c7f63SJim Harris          SCSI_ASC_NO_ADDITIONAL_SENSE,
1097f11c7f63SJim Harris          SCSI_ASCQ_NO_ADDITIONAL_SENSE
1098f11c7f63SJim Harris       );
1099f11c7f63SJim Harris       status = SATI_FAILURE_CHECK_RESPONSE_DATA;
1100f11c7f63SJim Harris    }
1101f11c7f63SJim Harris    else
1102f11c7f63SJim Harris    {
1103f11c7f63SJim Harris       if (sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE)
1104f11c7f63SJim Harris       {
1105f11c7f63SJim Harris          status = SATI_SEQUENCE_INCOMPLETE;
1106f11c7f63SJim Harris       }
1107f11c7f63SJim Harris       else
1108f11c7f63SJim Harris       {
1109f11c7f63SJim Harris          status = SATI_COMPLETE;
1110f11c7f63SJim Harris       }
1111f11c7f63SJim Harris    }
1112f11c7f63SJim Harris    return status;
1113f11c7f63SJim Harris }
1114f11c7f63SJim Harris 
1115f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_MODE_SELECT)
1116