xref: /freebsd/sys/dev/isci/scil/sati.c (revision f11c7f63056671247335df83a3fe80b94c6616ac)
1*f11c7f63SJim Harris /*-
2*f11c7f63SJim Harris  * This file is provided under a dual BSD/GPLv2 license.  When using or
3*f11c7f63SJim Harris  * redistributing this file, you may do so under either license.
4*f11c7f63SJim Harris  *
5*f11c7f63SJim Harris  * GPL LICENSE SUMMARY
6*f11c7f63SJim Harris  *
7*f11c7f63SJim Harris  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8*f11c7f63SJim Harris  *
9*f11c7f63SJim Harris  * This program is free software; you can redistribute it and/or modify
10*f11c7f63SJim Harris  * it under the terms of version 2 of the GNU General Public License as
11*f11c7f63SJim Harris  * published by the Free Software Foundation.
12*f11c7f63SJim Harris  *
13*f11c7f63SJim Harris  * This program is distributed in the hope that it will be useful, but
14*f11c7f63SJim Harris  * WITHOUT ANY WARRANTY; without even the implied warranty of
15*f11c7f63SJim Harris  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16*f11c7f63SJim Harris  * General Public License for more details.
17*f11c7f63SJim Harris  *
18*f11c7f63SJim Harris  * You should have received a copy of the GNU General Public License
19*f11c7f63SJim Harris  * along with this program; if not, write to the Free Software
20*f11c7f63SJim Harris  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21*f11c7f63SJim Harris  * The full GNU General Public License is included in this distribution
22*f11c7f63SJim Harris  * in the file called LICENSE.GPL.
23*f11c7f63SJim Harris  *
24*f11c7f63SJim Harris  * BSD LICENSE
25*f11c7f63SJim Harris  *
26*f11c7f63SJim Harris  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27*f11c7f63SJim Harris  * All rights reserved.
28*f11c7f63SJim Harris  *
29*f11c7f63SJim Harris  * Redistribution and use in source and binary forms, with or without
30*f11c7f63SJim Harris  * modification, are permitted provided that the following conditions
31*f11c7f63SJim Harris  * are met:
32*f11c7f63SJim Harris  *
33*f11c7f63SJim Harris  *   * Redistributions of source code must retain the above copyright
34*f11c7f63SJim Harris  *     notice, this list of conditions and the following disclaimer.
35*f11c7f63SJim Harris  *   * Redistributions in binary form must reproduce the above copyright
36*f11c7f63SJim Harris  *     notice, this list of conditions and the following disclaimer in
37*f11c7f63SJim Harris  *     the documentation and/or other materials provided with the
38*f11c7f63SJim Harris  *     distribution.
39*f11c7f63SJim Harris  *
40*f11c7f63SJim Harris  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41*f11c7f63SJim Harris  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42*f11c7f63SJim Harris  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43*f11c7f63SJim Harris  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44*f11c7f63SJim Harris  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45*f11c7f63SJim Harris  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46*f11c7f63SJim Harris  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47*f11c7f63SJim Harris  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48*f11c7f63SJim Harris  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49*f11c7f63SJim Harris  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50*f11c7f63SJim Harris  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51*f11c7f63SJim Harris  */
52*f11c7f63SJim Harris 
53*f11c7f63SJim Harris #include <sys/cdefs.h>
54*f11c7f63SJim Harris __FBSDID("$FreeBSD$");
55*f11c7f63SJim Harris 
56*f11c7f63SJim Harris /**
57*f11c7f63SJim Harris  * @file
58*f11c7f63SJim Harris  * @brief This file contains all of the method implementations that
59*f11c7f63SJim Harris  *        can be utilized by a user to perform SCSI-to-ATA Translation.
60*f11c7f63SJim Harris  *        SATI adheres to the www.t10.org SAT specification.
61*f11c7f63SJim Harris  *
62*f11c7f63SJim Harris  * For situations where compliance is not observed, the SATI will
63*f11c7f63SJim Harris  * return an error indication (most likely INVALID FIELD IN CDB sense data).
64*f11c7f63SJim Harris  */
65*f11c7f63SJim Harris 
66*f11c7f63SJim Harris #include <dev/isci/scil/sati.h>
67*f11c7f63SJim Harris #include <dev/isci/scil/sati_callbacks.h>
68*f11c7f63SJim Harris #include <dev/isci/scil/sati_util.h>
69*f11c7f63SJim Harris #include <dev/isci/scil/sati_report_luns.h>
70*f11c7f63SJim Harris #include <dev/isci/scil/sati_inquiry.h>
71*f11c7f63SJim Harris #include <dev/isci/scil/sati_mode_sense_6.h>
72*f11c7f63SJim Harris #include <dev/isci/scil/sati_mode_sense_10.h>
73*f11c7f63SJim Harris #include <dev/isci/scil/sati_mode_select.h>
74*f11c7f63SJim Harris #include <dev/isci/scil/sati_test_unit_ready.h>
75*f11c7f63SJim Harris #include <dev/isci/scil/sati_read_capacity.h>
76*f11c7f63SJim Harris #include <dev/isci/scil/sati_read.h>
77*f11c7f63SJim Harris #include <dev/isci/scil/sati_write.h>
78*f11c7f63SJim Harris #include <dev/isci/scil/sati_verify.h>
79*f11c7f63SJim Harris #include <dev/isci/scil/sati_synchronize_cache.h>
80*f11c7f63SJim Harris #include <dev/isci/scil/sati_lun_reset.h>
81*f11c7f63SJim Harris #include <dev/isci/scil/sati_start_stop_unit.h>
82*f11c7f63SJim Harris #include <dev/isci/scil/sati_request_sense.h>
83*f11c7f63SJim Harris #include <dev/isci/scil/sati_write_long.h>
84*f11c7f63SJim Harris #include <dev/isci/scil/sati_reassign_blocks.h>
85*f11c7f63SJim Harris #include <dev/isci/scil/sati_log_sense.h>
86*f11c7f63SJim Harris #include <dev/isci/scil/sati_abort_task_set.h>
87*f11c7f63SJim Harris #include <dev/isci/scil/sati_unmap.h>
88*f11c7f63SJim Harris #include <dev/isci/scil/sati_passthrough.h>
89*f11c7f63SJim Harris #include <dev/isci/scil/sati_write_and_verify.h>
90*f11c7f63SJim Harris #include <dev/isci/scil/sati_read_buffer.h>
91*f11c7f63SJim Harris #include <dev/isci/scil/sati_write_buffer.h>
92*f11c7f63SJim Harris #include <dev/isci/scil/intel_ata.h>
93*f11c7f63SJim Harris #include <dev/isci/scil/intel_scsi.h>
94*f11c7f63SJim Harris #include <dev/isci/scil/intel_sat.h>
95*f11c7f63SJim Harris 
96*f11c7f63SJim Harris //******************************************************************************
97*f11c7f63SJim Harris //* P R I V A T E   M E T H O D S
98*f11c7f63SJim Harris //******************************************************************************
99*f11c7f63SJim Harris 
100*f11c7f63SJim Harris /**
101*f11c7f63SJim Harris  * @brief This method performs the translation of ATA error register values
102*f11c7f63SJim Harris  *        into SCSI sense data.
103*f11c7f63SJim Harris  *        For more information on the parameter passed to this method please
104*f11c7f63SJim Harris  *        reference the sati_translate_response() method.
105*f11c7f63SJim Harris  *
106*f11c7f63SJim Harris  * @param[in] error This parameter specifies the contents of the ATA error
107*f11c7f63SJim Harris  *            register to be translated.
108*f11c7f63SJim Harris  *
109*f11c7f63SJim Harris  * @return none
110*f11c7f63SJim Harris  */
111*f11c7f63SJim Harris void sati_translate_error(
112*f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
113*f11c7f63SJim Harris    void                       * scsi_io,
114*f11c7f63SJim Harris    U8                           error
115*f11c7f63SJim Harris )
116*f11c7f63SJim Harris {
117*f11c7f63SJim Harris    if (error & ATA_ERROR_REG_NO_MEDIA_BIT)
118*f11c7f63SJim Harris    {
119*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
120*f11c7f63SJim Harris          sequence,
121*f11c7f63SJim Harris          scsi_io,
122*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
123*f11c7f63SJim Harris          SCSI_SENSE_NOT_READY,
124*f11c7f63SJim Harris          SCSI_ASC_MEDIUM_NOT_PRESENT,
125*f11c7f63SJim Harris          SCSI_ASCQ_MEDIUM_NOT_PRESENT
126*f11c7f63SJim Harris       );
127*f11c7f63SJim Harris    }
128*f11c7f63SJim Harris    else if (error & ATA_ERROR_REG_MEDIA_CHANGE_BIT)
129*f11c7f63SJim Harris    {
130*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
131*f11c7f63SJim Harris          sequence,
132*f11c7f63SJim Harris          scsi_io,
133*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
134*f11c7f63SJim Harris          SCSI_SENSE_UNIT_ATTENTION,
135*f11c7f63SJim Harris          SCSI_ASC_NOT_READY_TO_READY_CHANGE,
136*f11c7f63SJim Harris          SCSI_ASCQ_NOT_READY_TO_READY_CHANGE
137*f11c7f63SJim Harris       );
138*f11c7f63SJim Harris    }
139*f11c7f63SJim Harris    else if (error & ATA_ERROR_REG_MEDIA_CHANGE_REQUEST_BIT)
140*f11c7f63SJim Harris    {
141*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
142*f11c7f63SJim Harris          sequence,
143*f11c7f63SJim Harris          scsi_io,
144*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
145*f11c7f63SJim Harris          SCSI_SENSE_UNIT_ATTENTION,
146*f11c7f63SJim Harris          SCSI_ASC_MEDIUM_REMOVAL_REQUEST,
147*f11c7f63SJim Harris          SCSI_ASCQ_MEDIUM_REMOVAL_REQUEST
148*f11c7f63SJim Harris       );
149*f11c7f63SJim Harris    }
150*f11c7f63SJim Harris    else if (error & ATA_ERROR_REG_ID_NOT_FOUND_BIT)
151*f11c7f63SJim Harris    {
152*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
153*f11c7f63SJim Harris          sequence,
154*f11c7f63SJim Harris          scsi_io,
155*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
156*f11c7f63SJim Harris          SCSI_SENSE_ILLEGAL_REQUEST,
157*f11c7f63SJim Harris          SCSI_ASC_LBA_OUT_OF_RANGE,
158*f11c7f63SJim Harris          SCSI_ASCQ_LBA_OUT_OF_RANGE
159*f11c7f63SJim Harris       );
160*f11c7f63SJim Harris    }
161*f11c7f63SJim Harris    else if (error & ATA_ERROR_REG_UNCORRECTABLE_BIT)
162*f11c7f63SJim Harris    {
163*f11c7f63SJim Harris       //Mark the Sequence state as a read error so more sense data
164*f11c7f63SJim Harris       //can be returned later
165*f11c7f63SJim Harris       sequence->state = SATI_SEQUENCE_STATE_READ_ERROR;
166*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
167*f11c7f63SJim Harris          sequence,
168*f11c7f63SJim Harris          scsi_io,
169*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
170*f11c7f63SJim Harris          SCSI_SENSE_MEDIUM_ERROR,
171*f11c7f63SJim Harris          SCSI_ASC_UNRECOVERED_READ_ERROR,
172*f11c7f63SJim Harris          SCSI_ASCQ_UNRECOVERED_READ_ERROR
173*f11c7f63SJim Harris       );
174*f11c7f63SJim Harris    }
175*f11c7f63SJim Harris    else if (  (sequence->data_direction == SATI_DATA_DIRECTION_OUT)
176*f11c7f63SJim Harris            && (error & ATA_ERROR_REG_WRITE_PROTECTED_BIT) )
177*f11c7f63SJim Harris    {
178*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
179*f11c7f63SJim Harris          sequence,
180*f11c7f63SJim Harris          scsi_io,
181*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
182*f11c7f63SJim Harris          SCSI_SENSE_DATA_PROTECT,
183*f11c7f63SJim Harris          SCSI_ASC_WRITE_PROTECTED,
184*f11c7f63SJim Harris          SCSI_ASCQ_WRITE_PROTECTED
185*f11c7f63SJim Harris       );
186*f11c7f63SJim Harris    }
187*f11c7f63SJim Harris    else if (error & ATA_ERROR_REG_ICRC_BIT)
188*f11c7f63SJim Harris    {
189*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
190*f11c7f63SJim Harris          sequence,
191*f11c7f63SJim Harris          scsi_io,
192*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
193*f11c7f63SJim Harris          SCSI_SENSE_ABORTED_COMMAND,
194*f11c7f63SJim Harris          SCSI_ASC_IU_CRC_ERROR_DETECTED,
195*f11c7f63SJim Harris          SCSI_ASCQ_IU_CRC_ERROR_DETECTED
196*f11c7f63SJim Harris       );
197*f11c7f63SJim Harris    }
198*f11c7f63SJim Harris    else // (error & ATA_ERROR_REG_ABORT_BIT)
199*f11c7f63SJim Harris    {
200*f11c7f63SJim Harris       // The ABORT bit has the lowest precedence of all errors.
201*f11c7f63SJim Harris       // As a result, it is at the bottom of the conditional
202*f11c7f63SJim Harris       // statement.
203*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
204*f11c7f63SJim Harris          sequence,
205*f11c7f63SJim Harris          scsi_io,
206*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
207*f11c7f63SJim Harris          SCSI_SENSE_ABORTED_COMMAND,
208*f11c7f63SJim Harris          SCSI_ASC_NO_ADDITIONAL_SENSE,
209*f11c7f63SJim Harris          SCSI_ASCQ_NO_ADDITIONAL_SENSE
210*f11c7f63SJim Harris       );
211*f11c7f63SJim Harris    }
212*f11c7f63SJim Harris }
213*f11c7f63SJim Harris 
214*f11c7f63SJim Harris /**
215*f11c7f63SJim Harris  * @brief This method translates the supplied ATA payload data into the
216*f11c7f63SJim Harris  *        corresponding SCSI data.  This is necessary for SCSI commands
217*f11c7f63SJim Harris  *        that have well-defined payload data associated with them (e.g.
218*f11c7f63SJim Harris  *        READ CAPACITY).
219*f11c7f63SJim Harris  *
220*f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the sequence
221*f11c7f63SJim Harris  *             data associated with the translation.
222*f11c7f63SJim Harris  * @param[in]  ata_io This parameter specifies the ATA payload
223*f11c7f63SJim Harris  *             buffer location and size to be translated.
224*f11c7f63SJim Harris  * @param[out] scsi_output_data This parameter specifies the SCSI payload
225*f11c7f63SJim Harris  *             memory area into which the translator is to write.
226*f11c7f63SJim Harris  *
227*f11c7f63SJim Harris  * @return none
228*f11c7f63SJim Harris  */
229*f11c7f63SJim Harris static
230*f11c7f63SJim Harris void sati_translate_data(
231*f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
232*f11c7f63SJim Harris    void                       * ata_input_data,
233*f11c7f63SJim Harris    void                       * scsi_io
234*f11c7f63SJim Harris )
235*f11c7f63SJim Harris {
236*f11c7f63SJim Harris    // Update the device capabilities in the odd/crazy event something changed.
237*f11c7f63SJim Harris    sati_device_update_capabilities(
238*f11c7f63SJim Harris       sequence->device, (ATA_IDENTIFY_DEVICE_DATA_T*) ata_input_data
239*f11c7f63SJim Harris    );
240*f11c7f63SJim Harris 
241*f11c7f63SJim Harris    // Look at the first byte to determine the SCSI command to translate.
242*f11c7f63SJim Harris    switch (sequence->type)
243*f11c7f63SJim Harris    {
244*f11c7f63SJim Harris #if !defined(DISABLE_SATI_INQUIRY)
245*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_STANDARD:
246*f11c7f63SJim Harris          sati_inquiry_standard_translate_data(
247*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
248*f11c7f63SJim Harris          );
249*f11c7f63SJim Harris       break;
250*f11c7f63SJim Harris 
251*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER:
252*f11c7f63SJim Harris          sati_inquiry_serial_number_translate_data(
253*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
254*f11c7f63SJim Harris          );
255*f11c7f63SJim Harris       break;
256*f11c7f63SJim Harris 
257*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_DEVICE_ID:
258*f11c7f63SJim Harris          sati_inquiry_device_id_translate_data(
259*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
260*f11c7f63SJim Harris          );
261*f11c7f63SJim Harris       break;
262*f11c7f63SJim Harris 
263*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE:
264*f11c7f63SJim Harris          sati_inquiry_block_device_translate_data(
265*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
266*f11c7f63SJim Harris          );
267*f11c7f63SJim Harris       break;
268*f11c7f63SJim Harris 
269*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_ATA_INFORMATION:
270*f11c7f63SJim Harris          sati_inquiry_ata_information_translate_data(
271*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
272*f11c7f63SJim Harris          );
273*f11c7f63SJim Harris       break;
274*f11c7f63SJim Harris 
275*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_INQUIRY)
276*f11c7f63SJim Harris 
277*f11c7f63SJim Harris #if !defined(DISABLE_SATI_READ_CAPACITY)
278*f11c7f63SJim Harris       case SATI_SEQUENCE_READ_CAPACITY_10:
279*f11c7f63SJim Harris          sati_read_capacity_10_translate_data(sequence, ata_input_data, scsi_io);
280*f11c7f63SJim Harris       break;
281*f11c7f63SJim Harris 
282*f11c7f63SJim Harris       case SATI_SEQUENCE_READ_CAPACITY_16:
283*f11c7f63SJim Harris          sati_read_capacity_16_translate_data(sequence, ata_input_data, scsi_io);
284*f11c7f63SJim Harris       break;
285*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_READ_CAPACITY)
286*f11c7f63SJim Harris 
287*f11c7f63SJim Harris #if !defined(DISABLE_SATI_MODE_SENSE)
288*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_CACHING:
289*f11c7f63SJim Harris          sati_mode_sense_6_caching_translate_data(
290*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
291*f11c7f63SJim Harris          );
292*f11c7f63SJim Harris       break;
293*f11c7f63SJim Harris 
294*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_INFORMATIONAL_EXCP_CONTROL:
295*f11c7f63SJim Harris          sati_mode_sense_6_informational_excp_control_translate_data(
296*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
297*f11c7f63SJim Harris          );
298*f11c7f63SJim Harris       break;
299*f11c7f63SJim Harris 
300*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_READ_WRITE_ERROR:
301*f11c7f63SJim Harris          sati_mode_sense_6_read_write_error_translate_data(
302*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
303*f11c7f63SJim Harris          );
304*f11c7f63SJim Harris       break;
305*f11c7f63SJim Harris 
306*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_DISCONNECT_RECONNECT:
307*f11c7f63SJim Harris          sati_mode_sense_6_disconnect_reconnect_translate_data(
308*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
309*f11c7f63SJim Harris          );
310*f11c7f63SJim Harris       break;
311*f11c7f63SJim Harris 
312*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_CONTROL:
313*f11c7f63SJim Harris          sati_mode_sense_6_control_translate_data(
314*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
315*f11c7f63SJim Harris          );
316*f11c7f63SJim Harris       break;
317*f11c7f63SJim Harris 
318*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_ALL_PAGES:
319*f11c7f63SJim Harris          sati_mode_sense_6_all_pages_translate_data(
320*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
321*f11c7f63SJim Harris          );
322*f11c7f63SJim Harris       break;
323*f11c7f63SJim Harris 
324*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_POWER_CONDITION:
325*f11c7f63SJim Harris          sati_mode_sense_6_power_condition_translate_data(
326*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
327*f11c7f63SJim Harris          );
328*f11c7f63SJim Harris       break;
329*f11c7f63SJim Harris 
330*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_POWER_CONDITION:
331*f11c7f63SJim Harris          sati_mode_sense_10_power_condition_translate_data(
332*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
333*f11c7f63SJim Harris          );
334*f11c7f63SJim Harris       break;
335*f11c7f63SJim Harris 
336*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_CACHING:
337*f11c7f63SJim Harris          sati_mode_sense_10_caching_translate_data(
338*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
339*f11c7f63SJim Harris          );
340*f11c7f63SJim Harris       break;
341*f11c7f63SJim Harris 
342*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_INFORMATIONAL_EXCP_CONTROL:
343*f11c7f63SJim Harris          sati_mode_sense_10_informational_excp_control_translate_data(
344*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
345*f11c7f63SJim Harris          );
346*f11c7f63SJim Harris       break;
347*f11c7f63SJim Harris 
348*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_READ_WRITE_ERROR:
349*f11c7f63SJim Harris          sati_mode_sense_10_read_write_error_translate_data(
350*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
351*f11c7f63SJim Harris          );
352*f11c7f63SJim Harris       break;
353*f11c7f63SJim Harris 
354*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_DISCONNECT_RECONNECT:
355*f11c7f63SJim Harris          sati_mode_sense_10_disconnect_reconnect_translate_data(
356*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
357*f11c7f63SJim Harris          );
358*f11c7f63SJim Harris       break;
359*f11c7f63SJim Harris 
360*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_CONTROL:
361*f11c7f63SJim Harris          sati_mode_sense_10_control_translate_data(
362*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
363*f11c7f63SJim Harris          );
364*f11c7f63SJim Harris       break;
365*f11c7f63SJim Harris 
366*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_ALL_PAGES:
367*f11c7f63SJim Harris          sati_mode_sense_10_all_pages_translate_data(
368*f11c7f63SJim Harris             sequence, ata_input_data, scsi_io
369*f11c7f63SJim Harris          );
370*f11c7f63SJim Harris       break;
371*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_MODE_SENSE)
372*f11c7f63SJim Harris 
373*f11c7f63SJim Harris       default:
374*f11c7f63SJim Harris       break;
375*f11c7f63SJim Harris    }
376*f11c7f63SJim Harris }
377*f11c7f63SJim Harris 
378*f11c7f63SJim Harris //******************************************************************************
379*f11c7f63SJim Harris //* P U B L I C   M E T H O D S
380*f11c7f63SJim Harris //******************************************************************************
381*f11c7f63SJim Harris 
382*f11c7f63SJim Harris SATI_STATUS sati_translate_command(
383*f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
384*f11c7f63SJim Harris    SATI_DEVICE_T              * sati_device,
385*f11c7f63SJim Harris    void                       * scsi_io,
386*f11c7f63SJim Harris    void                       * ata_io
387*f11c7f63SJim Harris )
388*f11c7f63SJim Harris {
389*f11c7f63SJim Harris    SATI_STATUS   status = SATI_FAILURE;
390*f11c7f63SJim Harris    U8          * cdb = sati_cb_get_cdb_address(scsi_io);
391*f11c7f63SJim Harris 
392*f11c7f63SJim Harris    //No sense response has been set for the translation sequence yet
393*f11c7f63SJim Harris    sequence->is_sense_response_set          = FALSE;
394*f11c7f63SJim Harris    // Default to no translation response required
395*f11c7f63SJim Harris    sequence->is_translate_response_required = FALSE;
396*f11c7f63SJim Harris    // Assign sati_device to sequence
397*f11c7f63SJim Harris    sequence->device  = sati_device;
398*f11c7f63SJim Harris 
399*f11c7f63SJim Harris    /**
400*f11c7f63SJim Harris     * Fail any I/O request with LUN != 0
401*f11c7f63SJim Harris     */
402*f11c7f63SJim Harris    if (sati_cb_get_lun(scsi_io) != 0)
403*f11c7f63SJim Harris    {
404*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
405*f11c7f63SJim Harris          sequence,
406*f11c7f63SJim Harris          scsi_io,
407*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
408*f11c7f63SJim Harris          SCSI_SENSE_ILLEGAL_REQUEST,
409*f11c7f63SJim Harris          SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED,
410*f11c7f63SJim Harris          0
411*f11c7f63SJim Harris       );
412*f11c7f63SJim Harris       return SATI_FAILURE_CHECK_RESPONSE_DATA;
413*f11c7f63SJim Harris    }
414*f11c7f63SJim Harris 
415*f11c7f63SJim Harris    /**
416*f11c7f63SJim Harris     * SAT dictates:
417*f11c7f63SJim Harris     * - the NACA bit in the control byte (last byte) must be 0
418*f11c7f63SJim Harris     */
419*f11c7f63SJim Harris    if ( (sati_get_cdb_byte(cdb, sati_cb_get_cdb_length(scsi_io) - 1)
420*f11c7f63SJim Harris          & SCSI_CONTROL_BYTE_NACA_BIT_ENABLE))
421*f11c7f63SJim Harris    {
422*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
423*f11c7f63SJim Harris          sequence,
424*f11c7f63SJim Harris          scsi_io,
425*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
426*f11c7f63SJim Harris          SCSI_SENSE_ILLEGAL_REQUEST,
427*f11c7f63SJim Harris          SCSI_ASC_INVALID_FIELD_IN_CDB,
428*f11c7f63SJim Harris          SCSI_ASCQ_INVALID_FIELD_IN_CDB
429*f11c7f63SJim Harris       );
430*f11c7f63SJim Harris       return SATI_FAILURE_CHECK_RESPONSE_DATA;
431*f11c7f63SJim Harris    }
432*f11c7f63SJim Harris 
433*f11c7f63SJim Harris    /**
434*f11c7f63SJim Harris     * Per SAT "Error and sense reporting" section.  All subsequent IOs after
435*f11c7f63SJim Harris     * a device fault should receive INTERNAL TARGET FAILURE sense data.
436*f11c7f63SJim Harris     */
437*f11c7f63SJim Harris    if (sati_device->state == SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED)
438*f11c7f63SJim Harris    {
439*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
440*f11c7f63SJim Harris          sequence,
441*f11c7f63SJim Harris          scsi_io,
442*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
443*f11c7f63SJim Harris          SCSI_SENSE_HARDWARE_ERROR,
444*f11c7f63SJim Harris          SCSI_ASC_INTERNAL_TARGET_FAILURE,
445*f11c7f63SJim Harris          SCSI_ASCQ_INTERNAL_TARGET_FAILURE
446*f11c7f63SJim Harris       );
447*f11c7f63SJim Harris       return SATI_FAILURE_CHECK_RESPONSE_DATA;
448*f11c7f63SJim Harris    }
449*f11c7f63SJim Harris 
450*f11c7f63SJim Harris    if(sequence->state == SATI_SEQUENCE_STATE_INITIAL)
451*f11c7f63SJim Harris    {
452*f11c7f63SJim Harris       sequence->command_specific_data.scratch = 0;
453*f11c7f63SJim Harris       sequence->number_data_bytes_set = 0;
454*f11c7f63SJim Harris    }
455*f11c7f63SJim Harris 
456*f11c7f63SJim Harris 
457*f11c7f63SJim Harris #ifdef SATI_TRANSPORT_SUPPORTS_SATA
458*f11c7f63SJim Harris    {
459*f11c7f63SJim Harris       U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
460*f11c7f63SJim Harris       sati_set_sata_command_flag(register_fis);
461*f11c7f63SJim Harris       sati_set_sata_fis_type(register_fis, SATA_FIS_TYPE_REGH2D);
462*f11c7f63SJim Harris    }
463*f11c7f63SJim Harris #endif // SATI_TRANSPORT_SUPPORTS_SATA
464*f11c7f63SJim Harris 
465*f11c7f63SJim Harris    // Look at the first byte to determine the SCSI command to translate.
466*f11c7f63SJim Harris    switch (sati_get_cdb_byte(cdb, 0))
467*f11c7f63SJim Harris    {
468*f11c7f63SJim Harris #if !defined(DISABLE_SATI_REPORT_LUNS)
469*f11c7f63SJim Harris       case SCSI_REPORT_LUNS:
470*f11c7f63SJim Harris          status = sati_report_luns_translate_command(
471*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
472*f11c7f63SJim Harris                   );
473*f11c7f63SJim Harris       break;
474*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_REPORT_LUNS)
475*f11c7f63SJim Harris 
476*f11c7f63SJim Harris #if !defined(DISABLE_SATI_INQUIRY)
477*f11c7f63SJim Harris       case SCSI_INQUIRY:
478*f11c7f63SJim Harris          status = sati_inquiry_translate_command(
479*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
480*f11c7f63SJim Harris                   );
481*f11c7f63SJim Harris       break;
482*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_INQUIRY)
483*f11c7f63SJim Harris 
484*f11c7f63SJim Harris #if !defined(DISABLE_SATI_MODE_SENSE)
485*f11c7f63SJim Harris       case SCSI_MODE_SENSE_6:
486*f11c7f63SJim Harris          status = sati_mode_sense_6_translate_command(
487*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
488*f11c7f63SJim Harris                   );
489*f11c7f63SJim Harris       break;
490*f11c7f63SJim Harris 
491*f11c7f63SJim Harris       case SCSI_MODE_SENSE_10:
492*f11c7f63SJim Harris          status = sati_mode_sense_10_translate_command(
493*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
494*f11c7f63SJim Harris                   );
495*f11c7f63SJim Harris       break;
496*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_MODE_SENSE)
497*f11c7f63SJim Harris 
498*f11c7f63SJim Harris #if !defined(DISABLE_SATI_MODE_SELECT)
499*f11c7f63SJim Harris       case SCSI_MODE_SELECT_6:
500*f11c7f63SJim Harris          status = sati_mode_select_6_translate_command(
501*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
502*f11c7f63SJim Harris                   );
503*f11c7f63SJim Harris       break;
504*f11c7f63SJim Harris 
505*f11c7f63SJim Harris       case SCSI_MODE_SELECT_10:
506*f11c7f63SJim Harris          status = sati_mode_select_10_translate_command(
507*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
508*f11c7f63SJim Harris                   );
509*f11c7f63SJim Harris       break;
510*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_MODE_SELECT)
511*f11c7f63SJim Harris 
512*f11c7f63SJim Harris #if !defined(DISABLE_SATI_TEST_UNIT_READY)
513*f11c7f63SJim Harris       case SCSI_TEST_UNIT_READY:
514*f11c7f63SJim Harris          status = sati_test_unit_ready_translate_command(
515*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
516*f11c7f63SJim Harris                   );
517*f11c7f63SJim Harris       break;
518*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_TEST_UNIT_READY)
519*f11c7f63SJim Harris 
520*f11c7f63SJim Harris #if !defined(DISABLE_SATI_READ_CAPACITY)
521*f11c7f63SJim Harris       case SCSI_READ_CAPACITY_10:
522*f11c7f63SJim Harris          status = sati_read_capacity_10_translate_command(
523*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
524*f11c7f63SJim Harris                   );
525*f11c7f63SJim Harris       break;
526*f11c7f63SJim Harris 
527*f11c7f63SJim Harris       case SCSI_SERVICE_ACTION_IN_16:
528*f11c7f63SJim Harris          if ( (sati_get_cdb_byte(cdb, 1) & SCSI_SERVICE_ACTION_MASK)
529*f11c7f63SJim Harris               == SCSI_SERVICE_ACTION_IN_CODES_READ_CAPACITY_16)
530*f11c7f63SJim Harris             status = sati_read_capacity_16_translate_command(
531*f11c7f63SJim Harris                         sequence, scsi_io, ata_io
532*f11c7f63SJim Harris                      );
533*f11c7f63SJim Harris          else
534*f11c7f63SJim Harris             status = SATI_FAILURE_CHECK_RESPONSE_DATA;
535*f11c7f63SJim Harris       break;
536*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_READ_CAPACITY)
537*f11c7f63SJim Harris 
538*f11c7f63SJim Harris #if !defined(DISABLE_SATI_REQUEST_SENSE)
539*f11c7f63SJim Harris       case SCSI_REQUEST_SENSE:
540*f11c7f63SJim Harris          status = sati_request_sense_translate_command(
541*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
542*f11c7f63SJim Harris                   );
543*f11c7f63SJim Harris       break;
544*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_REQUEST_SENSE)
545*f11c7f63SJim Harris 
546*f11c7f63SJim Harris       case SCSI_READ_6:
547*f11c7f63SJim Harris          status = sati_read_6_translate_command(sequence, scsi_io, ata_io);
548*f11c7f63SJim Harris       break;
549*f11c7f63SJim Harris 
550*f11c7f63SJim Harris       case SCSI_READ_10:
551*f11c7f63SJim Harris          status = sati_read_10_translate_command(sequence, scsi_io, ata_io);
552*f11c7f63SJim Harris       break;
553*f11c7f63SJim Harris 
554*f11c7f63SJim Harris       case SCSI_READ_12:
555*f11c7f63SJim Harris          status = sati_read_12_translate_command(sequence, scsi_io, ata_io);
556*f11c7f63SJim Harris       break;
557*f11c7f63SJim Harris 
558*f11c7f63SJim Harris       case SCSI_READ_16:
559*f11c7f63SJim Harris          status = sati_read_16_translate_command(sequence, scsi_io, ata_io);
560*f11c7f63SJim Harris       break;
561*f11c7f63SJim Harris 
562*f11c7f63SJim Harris       case SCSI_WRITE_6:
563*f11c7f63SJim Harris          status = sati_write_6_translate_command(sequence, scsi_io, ata_io);
564*f11c7f63SJim Harris       break;
565*f11c7f63SJim Harris 
566*f11c7f63SJim Harris       case SCSI_WRITE_10:
567*f11c7f63SJim Harris          status = sati_write_10_translate_command(sequence, scsi_io, ata_io);
568*f11c7f63SJim Harris       break;
569*f11c7f63SJim Harris 
570*f11c7f63SJim Harris       case SCSI_WRITE_12:
571*f11c7f63SJim Harris          status = sati_write_12_translate_command(sequence, scsi_io, ata_io);
572*f11c7f63SJim Harris       break;
573*f11c7f63SJim Harris 
574*f11c7f63SJim Harris       case SCSI_WRITE_16:
575*f11c7f63SJim Harris          status = sati_write_16_translate_command(sequence, scsi_io, ata_io);
576*f11c7f63SJim Harris       break;
577*f11c7f63SJim Harris 
578*f11c7f63SJim Harris #if !defined(DISABLE_SATI_VERIFY)
579*f11c7f63SJim Harris       case SCSI_VERIFY_10:
580*f11c7f63SJim Harris          status = sati_verify_10_translate_command(sequence, scsi_io, ata_io);
581*f11c7f63SJim Harris       break;
582*f11c7f63SJim Harris 
583*f11c7f63SJim Harris       case SCSI_VERIFY_12:
584*f11c7f63SJim Harris          status = sati_verify_12_translate_command(sequence, scsi_io, ata_io);
585*f11c7f63SJim Harris       break;
586*f11c7f63SJim Harris 
587*f11c7f63SJim Harris       case SCSI_VERIFY_16:
588*f11c7f63SJim Harris          status = sati_verify_16_translate_command(sequence, scsi_io, ata_io);
589*f11c7f63SJim Harris       break;
590*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_VERIFY)
591*f11c7f63SJim Harris 
592*f11c7f63SJim Harris #if    !defined(DISABLE_SATI_WRITE_AND_VERIFY)  \
593*f11c7f63SJim Harris    && !defined(DISABLE_SATI_VERIFY)        \
594*f11c7f63SJim Harris    && !defined(DISABLE_SATI_WRITE)
595*f11c7f63SJim Harris 
596*f11c7f63SJim Harris       case SCSI_WRITE_AND_VERIFY_10:
597*f11c7f63SJim Harris          status = sati_write_and_verify_10_translate_command(sequence, scsi_io, ata_io);
598*f11c7f63SJim Harris       break;
599*f11c7f63SJim Harris 
600*f11c7f63SJim Harris       case SCSI_WRITE_AND_VERIFY_12:
601*f11c7f63SJim Harris          status = sati_write_and_verify_12_translate_command(sequence, scsi_io, ata_io);
602*f11c7f63SJim Harris       break;
603*f11c7f63SJim Harris 
604*f11c7f63SJim Harris       case SCSI_WRITE_AND_VERIFY_16:
605*f11c7f63SJim Harris          status = sati_write_and_verify_16_translate_command(sequence, scsi_io, ata_io);
606*f11c7f63SJim Harris       break;
607*f11c7f63SJim Harris #endif //    !defined(DISABLE_SATI_WRITE_AND_VERIFY)
608*f11c7f63SJim Harris       // && !defined(DISABLE_SATI_VERIFY)
609*f11c7f63SJim Harris       // && !defined(DISABLE_SATI_WRITE)
610*f11c7f63SJim Harris 
611*f11c7f63SJim Harris #if !defined(DISABLE_SATI_REASSIGN_BLOCKS)
612*f11c7f63SJim Harris       case SCSI_REASSIGN_BLOCKS:
613*f11c7f63SJim Harris          status = sati_reassign_blocks_translate_command(sequence, scsi_io, ata_io);
614*f11c7f63SJim Harris       break;
615*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
616*f11c7f63SJim Harris 
617*f11c7f63SJim Harris #if !defined(DISABLE_SATI_SYNCHRONIZE_CACHE)
618*f11c7f63SJim Harris       case SCSI_SYNCHRONIZE_CACHE_10:
619*f11c7f63SJim Harris       case SCSI_SYNCHRONIZE_CACHE_16:
620*f11c7f63SJim Harris          status = sati_synchronize_cache_translate_command(sequence, scsi_io, ata_io);
621*f11c7f63SJim Harris       break;
622*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_SYNCHRONIZE_CACHE)
623*f11c7f63SJim Harris 
624*f11c7f63SJim Harris #if !defined(DISABLE_SATI_START_STOP_UNIT)
625*f11c7f63SJim Harris       case SCSI_START_STOP_UNIT:
626*f11c7f63SJim Harris          status = sati_start_stop_unit_translate_command(
627*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
628*f11c7f63SJim Harris                   );
629*f11c7f63SJim Harris       break;
630*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_START_STOP_UNIT)
631*f11c7f63SJim Harris 
632*f11c7f63SJim Harris #if !defined(DISABLE_SATI_WRITE_LONG)
633*f11c7f63SJim Harris       case SCSI_WRITE_LONG_10:
634*f11c7f63SJim Harris       case SCSI_WRITE_LONG_16:
635*f11c7f63SJim Harris          status = sati_write_long_translate_command(sequence, scsi_io, ata_io);
636*f11c7f63SJim Harris       break;
637*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_WRITE_LONG)
638*f11c7f63SJim Harris 
639*f11c7f63SJim Harris #if !defined(DISABLE_SATI_LOG_SENSE)
640*f11c7f63SJim Harris       case SCSI_LOG_SENSE:
641*f11c7f63SJim Harris          status = sati_log_sense_translate_command(sequence, scsi_io, ata_io);
642*f11c7f63SJim Harris       break;
643*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_LOG_SENSE)
644*f11c7f63SJim Harris 
645*f11c7f63SJim Harris       case SCSI_PERSISTENT_RESERVE_IN:
646*f11c7f63SJim Harris       case SCSI_PERSISTENT_RESERVE_OUT:
647*f11c7f63SJim Harris          //These commands are not supported by SATI
648*f11c7f63SJim Harris          sati_scsi_sense_data_construct(
649*f11c7f63SJim Harris             sequence,
650*f11c7f63SJim Harris             scsi_io,
651*f11c7f63SJim Harris             SCSI_STATUS_CHECK_CONDITION,
652*f11c7f63SJim Harris             SCSI_SENSE_ILLEGAL_REQUEST,
653*f11c7f63SJim Harris             SCSI_ASC_INVALID_COMMAND_OPERATION_CODE,
654*f11c7f63SJim Harris             SCSI_ASCQ_INVALID_COMMAND_OPERATION_CODE
655*f11c7f63SJim Harris          );
656*f11c7f63SJim Harris          //returning status now to keep sense data set above
657*f11c7f63SJim Harris          return SATI_FAILURE_CHECK_RESPONSE_DATA;
658*f11c7f63SJim Harris       break;
659*f11c7f63SJim Harris 
660*f11c7f63SJim Harris #if !defined(DISABLE_SATI_UNMAP)
661*f11c7f63SJim Harris       case SCSI_UNMAP:
662*f11c7f63SJim Harris          status = sati_unmap_translate_command(sequence, scsi_io, ata_io);
663*f11c7f63SJim Harris       break;
664*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_UNMAP)
665*f11c7f63SJim Harris 
666*f11c7f63SJim Harris #if !defined(DISABLE_SATI_ATA_PASSTHROUGH)
667*f11c7f63SJim Harris       case SCSI_ATA_PASSTHRU_12:
668*f11c7f63SJim Harris           status = sati_passthrough_12_translate_command(sequence, scsi_io, ata_io);
669*f11c7f63SJim Harris       break;
670*f11c7f63SJim Harris 
671*f11c7f63SJim Harris       case SCSI_ATA_PASSTHRU_16:
672*f11c7f63SJim Harris           status = sati_passthrough_16_translate_command(sequence, scsi_io, ata_io);
673*f11c7f63SJim Harris       break;
674*f11c7f63SJim Harris 
675*f11c7f63SJim Harris #endif // !define(DISABLE_SATI_ATA_PASSTHRU)
676*f11c7f63SJim Harris 
677*f11c7f63SJim Harris #if !defined(DISABLE_SATI_READ_BUFFER)
678*f11c7f63SJim Harris       case SCSI_READ_BUFFER:
679*f11c7f63SJim Harris          status = sati_read_buffer_translate_command(sequence, scsi_io, ata_io);
680*f11c7f63SJim Harris       break;
681*f11c7f63SJim Harris #endif //!defined(DISABLE_SATI_READ_BUFFER)
682*f11c7f63SJim Harris 
683*f11c7f63SJim Harris #if !defined(DISABLE_SATI_WRITE_BUFFER)
684*f11c7f63SJim Harris       case SCSI_WRITE_BUFFER:
685*f11c7f63SJim Harris          status = sati_write_buffer_translate_command(sequence, scsi_io, ata_io);
686*f11c7f63SJim Harris       break;
687*f11c7f63SJim Harris #endif //!defined(DISABLE_SATI_WRITE_BUFFER)
688*f11c7f63SJim Harris       default:
689*f11c7f63SJim Harris          status = SATI_FAILURE_CHECK_RESPONSE_DATA;
690*f11c7f63SJim Harris       break;
691*f11c7f63SJim Harris    }
692*f11c7f63SJim Harris 
693*f11c7f63SJim Harris    if( (status == SATI_FAILURE_CHECK_RESPONSE_DATA) &&
694*f11c7f63SJim Harris        !(sequence->is_sense_response_set) )
695*f11c7f63SJim Harris    {
696*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
697*f11c7f63SJim Harris          sequence,
698*f11c7f63SJim Harris          scsi_io,
699*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
700*f11c7f63SJim Harris          SCSI_SENSE_ILLEGAL_REQUEST,
701*f11c7f63SJim Harris          SCSI_ASC_INVALID_FIELD_IN_CDB,
702*f11c7f63SJim Harris          SCSI_ASCQ_INVALID_FIELD_IN_CDB
703*f11c7f63SJim Harris       );
704*f11c7f63SJim Harris    }
705*f11c7f63SJim Harris    return status;
706*f11c7f63SJim Harris }
707*f11c7f63SJim Harris 
708*f11c7f63SJim Harris // -----------------------------------------------------------------------------
709*f11c7f63SJim Harris 
710*f11c7f63SJim Harris #if !defined(DISABLE_SATI_TASK_MANAGEMENT)
711*f11c7f63SJim Harris SATI_STATUS sati_translate_task_management(
712*f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
713*f11c7f63SJim Harris    SATI_DEVICE_T              * sati_device,
714*f11c7f63SJim Harris    void                       * scsi_task,
715*f11c7f63SJim Harris    void                       * ata_io
716*f11c7f63SJim Harris )
717*f11c7f63SJim Harris {
718*f11c7f63SJim Harris    SATI_STATUS status=SATI_FAILURE;
719*f11c7f63SJim Harris    U8 task_function = sati_cb_get_task_function(scsi_task);
720*f11c7f63SJim Harris 
721*f11c7f63SJim Harris    sequence->device = sati_device;
722*f11c7f63SJim Harris 
723*f11c7f63SJim Harris    switch (task_function)
724*f11c7f63SJim Harris    {
725*f11c7f63SJim Harris       /**
726*f11c7f63SJim Harris        * @todo We need to update the ABORT_TASK and ABORT_TASK_SET to be
727*f11c7f63SJim Harris        *       SAT compliant.
728*f11c7f63SJim Harris        */
729*f11c7f63SJim Harris       case SCSI_TASK_REQUEST_ABORT_TASK:
730*f11c7f63SJim Harris       case SCSI_TASK_REQUEST_LOGICAL_UNIT_RESET:
731*f11c7f63SJim Harris          status = sati_lun_reset_translate_command(sequence, scsi_task, ata_io);
732*f11c7f63SJim Harris       break;
733*f11c7f63SJim Harris 
734*f11c7f63SJim Harris       case SCSI_TASK_REQUEST_ABORT_TASK_SET:
735*f11c7f63SJim Harris #if !defined(DISABLE_SATI_ABORT_TASK_SET)
736*f11c7f63SJim Harris          status = sati_abort_task_set_translate_command(sequence, scsi_task, ata_io);
737*f11c7f63SJim Harris #else
738*f11c7f63SJim Harris          status = SATI_FAILURE;
739*f11c7f63SJim Harris #endif
740*f11c7f63SJim Harris          break;
741*f11c7f63SJim Harris       default:
742*f11c7f63SJim Harris          status = SATI_FAILURE;
743*f11c7f63SJim Harris       break;
744*f11c7f63SJim Harris    }
745*f11c7f63SJim Harris 
746*f11c7f63SJim Harris    return status;
747*f11c7f63SJim Harris }
748*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_TASK_MANAGEMENT)
749*f11c7f63SJim Harris 
750*f11c7f63SJim Harris // -----------------------------------------------------------------------------
751*f11c7f63SJim Harris #if      !defined(DISABLE_SATI_INQUIRY)            \
752*f11c7f63SJim Harris       || !defined(DISABLE_SATI_READY_CAPACITY)     \
753*f11c7f63SJim Harris       || !defined(DISABLE_SATI_MODE_SENSE)         \
754*f11c7f63SJim Harris       || !defined(DISABLE_SATI_MODE_SELECT)        \
755*f11c7f63SJim Harris       || !defined(DISABLE_SATI_REASSIGN_BLOCKS)    \
756*f11c7f63SJim Harris       || !defined(DISABLE_SATI_START_STOP_UNIT)    \
757*f11c7f63SJim Harris       || !defined(DISABLE_SATI_REQUEST_SENSE)      \
758*f11c7f63SJim Harris       || !defined(DISABLE_SATI_WRITE_LONG)         \
759*f11c7f63SJim Harris       || !defined(DISABLE_SATI_LOG_SENSE)          \
760*f11c7f63SJim Harris       || !defined(DISABLE_SATI_UNMAP)
761*f11c7f63SJim Harris 
762*f11c7f63SJim Harris static
763*f11c7f63SJim Harris SATI_STATUS sati_check_data_io(
764*f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
765*f11c7f63SJim Harris )
766*f11c7f63SJim Harris {
767*f11c7f63SJim Harris    if(sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE)
768*f11c7f63SJim Harris    {
769*f11c7f63SJim Harris       return SATI_SEQUENCE_INCOMPLETE;
770*f11c7f63SJim Harris    }
771*f11c7f63SJim Harris    else if(sequence->number_data_bytes_set < sequence->allocation_length)
772*f11c7f63SJim Harris    {
773*f11c7f63SJim Harris       return SATI_COMPLETE_IO_DONE_EARLY;
774*f11c7f63SJim Harris    }
775*f11c7f63SJim Harris    else
776*f11c7f63SJim Harris    {
777*f11c7f63SJim Harris       return SATI_COMPLETE;
778*f11c7f63SJim Harris    }
779*f11c7f63SJim Harris }
780*f11c7f63SJim Harris #endif   //    !defined(DISABLE_SATI_INQUIRY)
781*f11c7f63SJim Harris          // || !defined(DISABLE_SATI_READY_CAPACITY)
782*f11c7f63SJim Harris          // || !defined(DISABLE_SATI_MODE_SENSE)
783*f11c7f63SJim Harris          // || !defined(DISABLE_SATI_MODE_SELECT)
784*f11c7f63SJim Harris          // || !defined(DISABLE_SATI_REASSIGN_BLOCKS)
785*f11c7f63SJim Harris          // || !defined(DISABLE_SATI_START_STOP_UNIT)
786*f11c7f63SJim Harris          // || !defined(DISABLE_SATI_REQUEST_SENSE)
787*f11c7f63SJim Harris          // || !defined(DISABLE_SATI_WRITE_LONG)
788*f11c7f63SJim Harris          // || !defined(DISABLE_SATI_LOG_SENSE)
789*f11c7f63SJim Harris          // || !defined(DISABLE_SATI_UNMAP)
790*f11c7f63SJim Harris // -----------------------------------------------------------------------------
791*f11c7f63SJim Harris SATI_STATUS sati_translate_command_response(
792*f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
793*f11c7f63SJim Harris    void                       * scsi_io,
794*f11c7f63SJim Harris    void                       * ata_io
795*f11c7f63SJim Harris )
796*f11c7f63SJim Harris {
797*f11c7f63SJim Harris    SATI_STATUS   status       = SATI_COMPLETE;
798*f11c7f63SJim Harris    U8          * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
799*f11c7f63SJim Harris    U8            ata_status;
800*f11c7f63SJim Harris 
801*f11c7f63SJim Harris    /**
802*f11c7f63SJim Harris     * If the device fault bit is set in the status register, then
803*f11c7f63SJim Harris     * set the sense data and return.
804*f11c7f63SJim Harris     */
805*f11c7f63SJim Harris    ata_status = (U8) sati_get_ata_status(register_fis);
806*f11c7f63SJim Harris    if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT)
807*f11c7f63SJim Harris    {
808*f11c7f63SJim Harris       sati_scsi_sense_data_construct(
809*f11c7f63SJim Harris          sequence,
810*f11c7f63SJim Harris          scsi_io,
811*f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
812*f11c7f63SJim Harris          SCSI_SENSE_HARDWARE_ERROR,
813*f11c7f63SJim Harris          SCSI_ASC_INTERNAL_TARGET_FAILURE,
814*f11c7f63SJim Harris          SCSI_ASCQ_INTERNAL_TARGET_FAILURE
815*f11c7f63SJim Harris       );
816*f11c7f63SJim Harris 
817*f11c7f63SJim Harris       sequence->device->state = SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED;
818*f11c7f63SJim Harris 
819*f11c7f63SJim Harris       // Make sure that the terminate sequence is called to allow
820*f11c7f63SJim Harris       // translation logic to perform any cleanup before the IO is completed.
821*f11c7f63SJim Harris       sati_sequence_terminate(sequence,
822*f11c7f63SJim Harris                               scsi_io,
823*f11c7f63SJim Harris                               ata_io);
824*f11c7f63SJim Harris 
825*f11c7f63SJim Harris       return SATI_FAILURE_CHECK_RESPONSE_DATA;
826*f11c7f63SJim Harris    }
827*f11c7f63SJim Harris 
828*f11c7f63SJim Harris    // Look at the sequence type to determine the response translation method
829*f11c7f63SJim Harris    // to invoke.
830*f11c7f63SJim Harris    switch (sequence->type)
831*f11c7f63SJim Harris    {
832*f11c7f63SJim Harris #if !defined(DISABLE_SATI_TEST_UNIT_READY)
833*f11c7f63SJim Harris       case SATI_SEQUENCE_TEST_UNIT_READY:
834*f11c7f63SJim Harris          status = sati_test_unit_ready_translate_response(
835*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
836*f11c7f63SJim Harris                   );
837*f11c7f63SJim Harris       break;
838*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_TEST_UNIT_READY)
839*f11c7f63SJim Harris 
840*f11c7f63SJim Harris #if    !defined(DISABLE_SATI_INQUIRY)        \
841*f11c7f63SJim Harris     || !defined(DISABLE_SATI_READY_CAPACITY) \
842*f11c7f63SJim Harris     || !defined(DISABLE_SATI_MODE_SENSE)
843*f11c7f63SJim Harris 
844*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_EXECUTE_DEVICE_DIAG:
845*f11c7f63SJim Harris 
846*f11c7f63SJim Harris          if (ata_status & ATA_STATUS_REG_ERROR_BIT)
847*f11c7f63SJim Harris          {
848*f11c7f63SJim Harris             U8  error = (U8) sati_get_ata_error(register_fis);
849*f11c7f63SJim Harris             status    = SATI_FAILURE_CHECK_RESPONSE_DATA;
850*f11c7f63SJim Harris             sati_translate_error(sequence, scsi_io, error);
851*f11c7f63SJim Harris          }
852*f11c7f63SJim Harris          else
853*f11c7f63SJim Harris          {
854*f11c7f63SJim Harris             sati_inquiry_ata_information_finish_translation(
855*f11c7f63SJim Harris                sequence,
856*f11c7f63SJim Harris                scsi_io,
857*f11c7f63SJim Harris                ata_io
858*f11c7f63SJim Harris             );
859*f11c7f63SJim Harris             status = sati_check_data_io(sequence);
860*f11c7f63SJim Harris          }
861*f11c7f63SJim Harris       break;
862*f11c7f63SJim Harris 
863*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_STANDARD:
864*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_SUPPORTED_PAGES:
865*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER:
866*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE:
867*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_ATA_INFORMATION:
868*f11c7f63SJim Harris       case SATI_SEQUENCE_INQUIRY_DEVICE_ID:
869*f11c7f63SJim Harris       case SATI_SEQUENCE_READ_CAPACITY_10:
870*f11c7f63SJim Harris       case SATI_SEQUENCE_READ_CAPACITY_16:
871*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_CACHING:
872*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_INFORMATIONAL_EXCP_CONTROL:
873*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_READ_WRITE_ERROR:
874*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_DISCONNECT_RECONNECT:
875*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_CONTROL:
876*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_POWER_CONDITION:
877*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_6_ALL_PAGES:
878*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_CACHING:
879*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_INFORMATIONAL_EXCP_CONTROL:
880*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_READ_WRITE_ERROR:
881*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_CONTROL:
882*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_POWER_CONDITION:
883*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_DISCONNECT_RECONNECT:
884*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SENSE_10_ALL_PAGES:
885*f11c7f63SJim Harris          // Did an error occur during the IO request?
886*f11c7f63SJim Harris          if (ata_status & ATA_STATUS_REG_ERROR_BIT)
887*f11c7f63SJim Harris          {
888*f11c7f63SJim Harris             U8  error = (U8) sati_get_ata_error(register_fis);
889*f11c7f63SJim Harris             status    = SATI_FAILURE_CHECK_RESPONSE_DATA;
890*f11c7f63SJim Harris             sati_translate_error(sequence, scsi_io, error);
891*f11c7f63SJim Harris          }
892*f11c7f63SJim Harris          else
893*f11c7f63SJim Harris          {
894*f11c7f63SJim Harris             void * ata_data = sati_cb_get_ata_data_address(ata_io);
895*f11c7f63SJim Harris 
896*f11c7f63SJim Harris             if(ata_data == NULL)
897*f11c7f63SJim Harris             {
898*f11c7f63SJim Harris                status = SATI_FAILURE;
899*f11c7f63SJim Harris             }
900*f11c7f63SJim Harris             else
901*f11c7f63SJim Harris             {
902*f11c7f63SJim Harris                sati_translate_data(sequence, ata_data, scsi_io);
903*f11c7f63SJim Harris                status = sati_check_data_io(sequence);
904*f11c7f63SJim Harris             }
905*f11c7f63SJim Harris          }
906*f11c7f63SJim Harris       break;
907*f11c7f63SJim Harris #endif //    !defined(DISABLE_SATI_INQUIRY)
908*f11c7f63SJim Harris        // && !defined(DISABLE_SATI_READY_CAPACITY)
909*f11c7f63SJim Harris        // && !defined(DISABLE_SATI_MODE_SENSE)
910*f11c7f63SJim Harris 
911*f11c7f63SJim Harris #if !defined(DISABLE_SATI_MODE_SELECT)
912*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SELECT_MODE_PAGE_CACHING:
913*f11c7f63SJim Harris 
914*f11c7f63SJim Harris          status = sati_mode_select_translate_response(
915*f11c7f63SJim Harris             sequence, scsi_io, ata_io
916*f11c7f63SJim Harris                );
917*f11c7f63SJim Harris          if(status == SATI_COMPLETE)
918*f11c7f63SJim Harris          {
919*f11c7f63SJim Harris             status = sati_check_data_io(sequence);
920*f11c7f63SJim Harris          }
921*f11c7f63SJim Harris          break;
922*f11c7f63SJim Harris 
923*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SELECT_MODE_POWER_CONDITION:
924*f11c7f63SJim Harris       case SATI_SEQUENCE_MODE_SELECT_MODE_INFORMATION_EXCEPT_CONTROL:
925*f11c7f63SJim Harris          // Did an error occur during the IO request?
926*f11c7f63SJim Harris          if (ata_status & ATA_STATUS_REG_ERROR_BIT)
927*f11c7f63SJim Harris          {
928*f11c7f63SJim Harris             U8  error = (U8) sati_get_ata_error(register_fis);
929*f11c7f63SJim Harris             status    = SATI_FAILURE_CHECK_RESPONSE_DATA;
930*f11c7f63SJim Harris             sati_translate_error(sequence, scsi_io, error);
931*f11c7f63SJim Harris          }
932*f11c7f63SJim Harris          else
933*f11c7f63SJim Harris          {
934*f11c7f63SJim Harris             status = sati_check_data_io(sequence);
935*f11c7f63SJim Harris          }
936*f11c7f63SJim Harris       break;
937*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_MODE_SELECT)
938*f11c7f63SJim Harris 
939*f11c7f63SJim Harris #if !defined(DISABLE_SATI_WRITE_AND_VERIFY)
940*f11c7f63SJim Harris       case SATI_SEQUENCE_WRITE_AND_VERIFY:
941*f11c7f63SJim Harris 
942*f11c7f63SJim Harris          if (ata_status & ATA_STATUS_REG_ERROR_BIT)
943*f11c7f63SJim Harris          {
944*f11c7f63SJim Harris             U8  error = (U8) sati_get_ata_error(register_fis);
945*f11c7f63SJim Harris             sati_translate_error(sequence, scsi_io, error);
946*f11c7f63SJim Harris 
947*f11c7f63SJim Harris             return SATI_FAILURE_CHECK_RESPONSE_DATA;
948*f11c7f63SJim Harris          }
949*f11c7f63SJim Harris          else
950*f11c7f63SJim Harris          {
951*f11c7f63SJim Harris             status = sati_write_and_verify_translate_response(
952*f11c7f63SJim Harris                         sequence,
953*f11c7f63SJim Harris                         scsi_io,
954*f11c7f63SJim Harris                         ata_io
955*f11c7f63SJim Harris                      );
956*f11c7f63SJim Harris          }
957*f11c7f63SJim Harris       break;
958*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY)
959*f11c7f63SJim Harris 
960*f11c7f63SJim Harris       case SATI_SEQUENCE_READ_6:
961*f11c7f63SJim Harris       case SATI_SEQUENCE_READ_10:
962*f11c7f63SJim Harris       case SATI_SEQUENCE_READ_12:
963*f11c7f63SJim Harris       case SATI_SEQUENCE_READ_16:
964*f11c7f63SJim Harris       case SATI_SEQUENCE_WRITE_6:
965*f11c7f63SJim Harris       case SATI_SEQUENCE_WRITE_10:
966*f11c7f63SJim Harris       case SATI_SEQUENCE_WRITE_12:
967*f11c7f63SJim Harris       case SATI_SEQUENCE_WRITE_16:
968*f11c7f63SJim Harris       case SATI_SEQUENCE_VERIFY_10:
969*f11c7f63SJim Harris       case SATI_SEQUENCE_VERIFY_12:
970*f11c7f63SJim Harris       case SATI_SEQUENCE_VERIFY_16:
971*f11c7f63SJim Harris       case SATI_SEQUENCE_SYNCHRONIZE_CACHE:
972*f11c7f63SJim Harris          if (ata_status & ATA_STATUS_REG_ERROR_BIT)
973*f11c7f63SJim Harris          {
974*f11c7f63SJim Harris             U8  error = (U8) sati_get_ata_error(register_fis);
975*f11c7f63SJim Harris             status    = SATI_FAILURE_CHECK_RESPONSE_DATA;
976*f11c7f63SJim Harris             sati_translate_error(sequence, scsi_io, error);
977*f11c7f63SJim Harris 
978*f11c7f63SJim Harris             if(sequence->state == SATI_SEQUENCE_STATE_READ_ERROR )
979*f11c7f63SJim Harris             {
980*f11c7f63SJim Harris                sati_scsi_read_error_sense_construct(
981*f11c7f63SJim Harris                   sequence,
982*f11c7f63SJim Harris                   scsi_io,
983*f11c7f63SJim Harris                   ata_io,
984*f11c7f63SJim Harris                   SCSI_STATUS_CHECK_CONDITION,
985*f11c7f63SJim Harris                   SCSI_SENSE_MEDIUM_ERROR,
986*f11c7f63SJim Harris                   SCSI_ASC_UNRECOVERED_READ_ERROR,
987*f11c7f63SJim Harris                   SCSI_ASCQ_UNRECOVERED_READ_ERROR
988*f11c7f63SJim Harris                );
989*f11c7f63SJim Harris                sequence->state = SATI_SEQUENCE_STATE_FINAL;
990*f11c7f63SJim Harris             }
991*f11c7f63SJim Harris          }
992*f11c7f63SJim Harris          else
993*f11c7f63SJim Harris          {
994*f11c7f63SJim Harris             // We haven't satisified the transfer count from the original
995*f11c7f63SJim Harris             // SCSI CDB.  As a result, we need to re-issue the command
996*f11c7f63SJim Harris             // with updated logical block address and transfer count.
997*f11c7f63SJim Harris             if (sequence->command_specific_data.scratch)
998*f11c7f63SJim Harris             {
999*f11c7f63SJim Harris                /** @todo update the contents of the CDB directly?  Should be
1000*f11c7f63SJim Harris                 *  done during previous command translation?
1001*f11c7f63SJim Harris                 */
1002*f11c7f63SJim Harris                status = SATI_SEQUENCE_INCOMPLETE;
1003*f11c7f63SJim Harris             }
1004*f11c7f63SJim Harris          }
1005*f11c7f63SJim Harris       break;
1006*f11c7f63SJim Harris 
1007*f11c7f63SJim Harris #if !defined(DISABLE_SATI_READ_BUFFER)
1008*f11c7f63SJim Harris       case SATI_SEQUENCE_READ_BUFFER:
1009*f11c7f63SJim Harris          status = sati_read_buffer_translate_response(
1010*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
1011*f11c7f63SJim Harris                   );
1012*f11c7f63SJim Harris 
1013*f11c7f63SJim Harris          if(status == SATI_COMPLETE)
1014*f11c7f63SJim Harris          {
1015*f11c7f63SJim Harris             status = sati_check_data_io(sequence);
1016*f11c7f63SJim Harris          }
1017*f11c7f63SJim Harris       break;
1018*f11c7f63SJim Harris #endif //!defined(DISABLE_SATI_READ_BUFFER)
1019*f11c7f63SJim Harris 
1020*f11c7f63SJim Harris #if !defined(DISABLE_SATI_WRITE_BUFFER)
1021*f11c7f63SJim Harris       case SATI_SEQUENCE_WRITE_BUFFER:
1022*f11c7f63SJim Harris       case SATI_SEQUENCE_WRITE_BUFFER_MICROCODE:
1023*f11c7f63SJim Harris          status = sati_write_buffer_translate_response(
1024*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
1025*f11c7f63SJim Harris                   );
1026*f11c7f63SJim Harris       break;
1027*f11c7f63SJim Harris #endif //!defined(DISABLE_SATI_WRITE_BUFFER)
1028*f11c7f63SJim Harris 
1029*f11c7f63SJim Harris #if !defined(DISABLE_SATI_REASSIGN_BLOCKS)
1030*f11c7f63SJim Harris       case SATI_SEQUENCE_REASSIGN_BLOCKS:
1031*f11c7f63SJim Harris          status = sati_reassign_blocks_translate_response(
1032*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
1033*f11c7f63SJim Harris                   );
1034*f11c7f63SJim Harris          if(status == SATI_COMPLETE)
1035*f11c7f63SJim Harris          {
1036*f11c7f63SJim Harris             status = sati_check_data_io(sequence);
1037*f11c7f63SJim Harris          }
1038*f11c7f63SJim Harris       break;
1039*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
1040*f11c7f63SJim Harris 
1041*f11c7f63SJim Harris #if !defined(DISABLE_SATI_START_STOP_UNIT)
1042*f11c7f63SJim Harris       case SATI_SEQUENCE_START_STOP_UNIT:
1043*f11c7f63SJim Harris          status = sati_start_stop_unit_translate_response(
1044*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
1045*f11c7f63SJim Harris                   );
1046*f11c7f63SJim Harris          if(status == SATI_COMPLETE)
1047*f11c7f63SJim Harris          {
1048*f11c7f63SJim Harris             status = sati_check_data_io(sequence);
1049*f11c7f63SJim Harris          }
1050*f11c7f63SJim Harris       break;
1051*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_START_STOP_UNIT)
1052*f11c7f63SJim Harris 
1053*f11c7f63SJim Harris #if !defined(DISABLE_SATI_REQUEST_SENSE)
1054*f11c7f63SJim Harris       case SATI_SEQUENCE_REQUEST_SENSE_SMART_RETURN_STATUS:
1055*f11c7f63SJim Harris       case SATI_SEQUENCE_REQUEST_SENSE_CHECK_POWER_MODE:
1056*f11c7f63SJim Harris          status = sati_request_sense_translate_response(
1057*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
1058*f11c7f63SJim Harris                   );
1059*f11c7f63SJim Harris          if(status == SATI_COMPLETE)
1060*f11c7f63SJim Harris          {
1061*f11c7f63SJim Harris             status = sati_check_data_io(sequence);
1062*f11c7f63SJim Harris          }
1063*f11c7f63SJim Harris       break;
1064*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_REQUEST_SENSE)
1065*f11c7f63SJim Harris 
1066*f11c7f63SJim Harris #if !defined(DISABLE_SATI_WRITE_LONG)
1067*f11c7f63SJim Harris       case SATI_SEQUENCE_WRITE_LONG:
1068*f11c7f63SJim Harris          status = sati_write_long_translate_response(
1069*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
1070*f11c7f63SJim Harris                   );
1071*f11c7f63SJim Harris          if(status == SATI_COMPLETE)
1072*f11c7f63SJim Harris          {
1073*f11c7f63SJim Harris             status = sati_check_data_io(sequence);
1074*f11c7f63SJim Harris          }
1075*f11c7f63SJim Harris       break;
1076*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_WRITE_LONG)
1077*f11c7f63SJim Harris 
1078*f11c7f63SJim Harris #if !defined(DISABLE_SATI_LOG_SENSE)
1079*f11c7f63SJim Harris       case SATI_SEQUENCE_LOG_SENSE_SUPPORTED_LOG_PAGE:
1080*f11c7f63SJim Harris       case SATI_SEQUENCE_LOG_SENSE_SELF_TEST_LOG_PAGE:
1081*f11c7f63SJim Harris       case SATI_SEQUENCE_LOG_SENSE_EXTENDED_SELF_TEST_LOG_PAGE:
1082*f11c7f63SJim Harris       case SATI_SEQUENCE_LOG_SENSE_INFO_EXCEPTION_LOG_PAGE:
1083*f11c7f63SJim Harris          status = sati_log_sense_translate_response(
1084*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
1085*f11c7f63SJim Harris                   );
1086*f11c7f63SJim Harris          if(status == SATI_COMPLETE)
1087*f11c7f63SJim Harris          {
1088*f11c7f63SJim Harris             status = sati_check_data_io(sequence);
1089*f11c7f63SJim Harris          }
1090*f11c7f63SJim Harris       break;
1091*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_LOG_SENSE)
1092*f11c7f63SJim Harris 
1093*f11c7f63SJim Harris #if !defined(DISABLE_SATI_UNMAP)
1094*f11c7f63SJim Harris       case SATI_SEQUENCE_UNMAP:
1095*f11c7f63SJim Harris          status = sati_unmap_translate_response(
1096*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
1097*f11c7f63SJim Harris                   );
1098*f11c7f63SJim Harris          if(status == SATI_COMPLETE)
1099*f11c7f63SJim Harris          {
1100*f11c7f63SJim Harris             status = sati_check_data_io(sequence);
1101*f11c7f63SJim Harris          }
1102*f11c7f63SJim Harris       break;
1103*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_UNMAP)
1104*f11c7f63SJim Harris 
1105*f11c7f63SJim Harris #if !defined(DISABLE_SATI_ATA_PASSTHROUGH)
1106*f11c7f63SJim Harris       case SATI_SEQUENCE_ATA_PASSTHROUGH_12:
1107*f11c7f63SJim Harris       case SATI_SEQUENCE_ATA_PASSTHROUGH_16:
1108*f11c7f63SJim Harris          status = sati_passthrough_translate_response(
1109*f11c7f63SJim Harris                      sequence, scsi_io, ata_io
1110*f11c7f63SJim Harris                   );
1111*f11c7f63SJim Harris       break;
1112*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_ATA_PASSTHROUGH)
1113*f11c7f63SJim Harris 
1114*f11c7f63SJim Harris       default:
1115*f11c7f63SJim Harris          status = SATI_FAILURE_INVALID_SEQUENCE_TYPE;
1116*f11c7f63SJim Harris       break;
1117*f11c7f63SJim Harris    }
1118*f11c7f63SJim Harris 
1119*f11c7f63SJim Harris    return status;
1120*f11c7f63SJim Harris }
1121*f11c7f63SJim Harris 
1122*f11c7f63SJim Harris // -----------------------------------------------------------------------------
1123*f11c7f63SJim Harris 
1124*f11c7f63SJim Harris #if !defined(DISABLE_SATI_TASK_MANAGEMENT)
1125*f11c7f63SJim Harris SATI_STATUS sati_translate_task_response(
1126*f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1127*f11c7f63SJim Harris    void                       * scsi_io,
1128*f11c7f63SJim Harris    void                       * ata_io
1129*f11c7f63SJim Harris )
1130*f11c7f63SJim Harris {
1131*f11c7f63SJim Harris    SATI_STATUS   status       = SATI_FAILURE_CHECK_RESPONSE_DATA;
1132*f11c7f63SJim Harris    U8          * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
1133*f11c7f63SJim Harris    U8            ata_status;
1134*f11c7f63SJim Harris 
1135*f11c7f63SJim Harris    /**
1136*f11c7f63SJim Harris     * If the device fault bit is set in the status register, then
1137*f11c7f63SJim Harris     * set the sense data and return.
1138*f11c7f63SJim Harris     */
1139*f11c7f63SJim Harris    ata_status = (U8) sati_get_ata_status(register_fis);
1140*f11c7f63SJim Harris    if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT)
1141*f11c7f63SJim Harris    {
1142*f11c7f63SJim Harris       sati_scsi_response_data_construct(
1143*f11c7f63SJim Harris          sequence,
1144*f11c7f63SJim Harris          scsi_io,
1145*f11c7f63SJim Harris          SCSI_TASK_MGMT_FUNC_FAILED
1146*f11c7f63SJim Harris       );
1147*f11c7f63SJim Harris       return SATI_FAILURE_CHECK_RESPONSE_DATA;
1148*f11c7f63SJim Harris    }
1149*f11c7f63SJim Harris 
1150*f11c7f63SJim Harris    // Look at the sequence type to determine the response translation method
1151*f11c7f63SJim Harris    // to invoke.
1152*f11c7f63SJim Harris    switch (sequence->type)
1153*f11c7f63SJim Harris    {
1154*f11c7f63SJim Harris       case SATI_SEQUENCE_LUN_RESET:
1155*f11c7f63SJim Harris          if (ata_status & ATA_STATUS_REG_ERROR_BIT)
1156*f11c7f63SJim Harris          {
1157*f11c7f63SJim Harris             sati_scsi_response_data_construct(
1158*f11c7f63SJim Harris                sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED);
1159*f11c7f63SJim Harris          }
1160*f11c7f63SJim Harris          else
1161*f11c7f63SJim Harris          {
1162*f11c7f63SJim Harris             sati_scsi_response_data_construct(
1163*f11c7f63SJim Harris                sequence, scsi_io, SCSI_TASK_MGMT_FUNC_COMPLETE);
1164*f11c7f63SJim Harris          }
1165*f11c7f63SJim Harris 
1166*f11c7f63SJim Harris          status = SATI_COMPLETE;
1167*f11c7f63SJim Harris       break;
1168*f11c7f63SJim Harris 
1169*f11c7f63SJim Harris #if !defined(DISABLE_SATI_ABORT_TASK_SET)
1170*f11c7f63SJim Harris       case SATI_SEQUENCE_ABORT_TASK_SET:
1171*f11c7f63SJim Harris          if (ata_status & ATA_STATUS_REG_ERROR_BIT)
1172*f11c7f63SJim Harris          {
1173*f11c7f63SJim Harris             sati_scsi_response_data_construct(
1174*f11c7f63SJim Harris                sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED);
1175*f11c7f63SJim Harris          }
1176*f11c7f63SJim Harris          else
1177*f11c7f63SJim Harris          {
1178*f11c7f63SJim Harris             void * ata_data = sati_cb_get_ata_data_address(ata_io);
1179*f11c7f63SJim Harris 
1180*f11c7f63SJim Harris             if(ata_data == NULL)
1181*f11c7f63SJim Harris             {
1182*f11c7f63SJim Harris                status = SATI_FAILURE;
1183*f11c7f63SJim Harris             }
1184*f11c7f63SJim Harris             else
1185*f11c7f63SJim Harris             {
1186*f11c7f63SJim Harris                status = sati_abort_task_set_translate_data(
1187*f11c7f63SJim Harris                            sequence,
1188*f11c7f63SJim Harris                            ata_data,
1189*f11c7f63SJim Harris                            scsi_io
1190*f11c7f63SJim Harris                         );
1191*f11c7f63SJim Harris             }
1192*f11c7f63SJim Harris          }
1193*f11c7f63SJim Harris       break;
1194*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_ABORT_TASK_SET)
1195*f11c7f63SJim Harris 
1196*f11c7f63SJim Harris       default:
1197*f11c7f63SJim Harris          status = SATI_FAILURE_INVALID_SEQUENCE_TYPE;
1198*f11c7f63SJim Harris       break;
1199*f11c7f63SJim Harris    }
1200*f11c7f63SJim Harris 
1201*f11c7f63SJim Harris    return status;
1202*f11c7f63SJim Harris }
1203*f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_TASK_MANAGEMENT)
1204*f11c7f63SJim Harris 
1205*f11c7f63SJim Harris #if !defined(ENABLE_MINIMUM_MEMORY_MODE)
1206*f11c7f63SJim Harris U32 sati_get_sat_compliance_version(
1207*f11c7f63SJim Harris    void
1208*f11c7f63SJim Harris )
1209*f11c7f63SJim Harris {
1210*f11c7f63SJim Harris    return 2;  // Compliant with SAT-2.
1211*f11c7f63SJim Harris }
1212*f11c7f63SJim Harris 
1213*f11c7f63SJim Harris U32 sati_get_sat_compliance_version_revision(
1214*f11c7f63SJim Harris    void
1215*f11c7f63SJim Harris )
1216*f11c7f63SJim Harris {
1217*f11c7f63SJim Harris    return 7;  // Compliant with SAT-2 revision 7.
1218*f11c7f63SJim Harris }
1219*f11c7f63SJim Harris 
1220*f11c7f63SJim Harris #endif // !defined(ENABLE_MINIMUM_MEMORY_MODE)
1221*f11c7f63SJim Harris 
1222*f11c7f63SJim Harris U16 sati_get_number_data_bytes_set(
1223*f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
1224*f11c7f63SJim Harris )
1225*f11c7f63SJim Harris {
1226*f11c7f63SJim Harris    return sequence->number_data_bytes_set;
1227*f11c7f63SJim Harris }
1228*f11c7f63SJim Harris 
1229*f11c7f63SJim Harris void sati_sequence_construct(
1230*f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence
1231*f11c7f63SJim Harris )
1232*f11c7f63SJim Harris {
1233*f11c7f63SJim Harris    sequence->state = SATI_SEQUENCE_STATE_INITIAL;
1234*f11c7f63SJim Harris }
1235*f11c7f63SJim Harris 
1236*f11c7f63SJim Harris void sati_sequence_terminate(
1237*f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
1238*f11c7f63SJim Harris    void                       * scsi_io,
1239*f11c7f63SJim Harris    void                       * ata_io
1240*f11c7f63SJim Harris )
1241*f11c7f63SJim Harris {
1242*f11c7f63SJim Harris    // Decode the sequence type to determine how to handle the termination
1243*f11c7f63SJim Harris    // of the the translation method.
1244*f11c7f63SJim Harris    switch (sequence->type)
1245*f11c7f63SJim Harris    {
1246*f11c7f63SJim Harris    case SATI_SEQUENCE_UNMAP:
1247*f11c7f63SJim Harris       sati_unmap_terminate(sequence,scsi_io,ata_io);
1248*f11c7f63SJim Harris    break;
1249*f11c7f63SJim Harris    }
1250*f11c7f63SJim Harris }
1251