sati.c revision 256281
1234285Sdim/*-
2234285Sdim * This file is provided under a dual BSD/GPLv2 license.  When using or
3234285Sdim * redistributing this file, you may do so under either license.
4234285Sdim *
5234285Sdim * GPL LICENSE SUMMARY
6234285Sdim *
7234285Sdim * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8234285Sdim *
9234285Sdim * This program is free software; you can redistribute it and/or modify
10234285Sdim * it under the terms of version 2 of the GNU General Public License as
11234285Sdim * published by the Free Software Foundation.
12234285Sdim *
13234285Sdim * This program is distributed in the hope that it will be useful, but
14234285Sdim * WITHOUT ANY WARRANTY; without even the implied warranty of
15234285Sdim * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16234285Sdim * General Public License for more details.
17234285Sdim *
18234285Sdim * You should have received a copy of the GNU General Public License
19234285Sdim * along with this program; if not, write to the Free Software
20234285Sdim * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21234285Sdim * The full GNU General Public License is included in this distribution
22234285Sdim * in the file called LICENSE.GPL.
23234285Sdim *
24234285Sdim * BSD LICENSE
25234285Sdim *
26234285Sdim * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27234285Sdim * All rights reserved.
28234285Sdim *
29234285Sdim * Redistribution and use in source and binary forms, with or without
30234285Sdim * modification, are permitted provided that the following conditions
31234285Sdim * are met:
32234285Sdim *
33234285Sdim *   * Redistributions of source code must retain the above copyright
34234285Sdim *     notice, this list of conditions and the following disclaimer.
35234285Sdim *   * Redistributions in binary form must reproduce the above copyright
36234285Sdim *     notice, this list of conditions and the following disclaimer in
37234285Sdim *     the documentation and/or other materials provided with the
38234285Sdim *     distribution.
39234285Sdim *
40234285Sdim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41234285Sdim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42234285Sdim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43234285Sdim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44234285Sdim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45234285Sdim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46234285Sdim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47234285Sdim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48234285Sdim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49234285Sdim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50234285Sdim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51234285Sdim */
52234285Sdim
53234285Sdim#include <sys/cdefs.h>
54234285Sdim__FBSDID("$FreeBSD: stable/10/sys/dev/isci/scil/sati.c 240518 2012-09-14 21:28:56Z eadler $");
55234285Sdim
56234285Sdim/**
57234285Sdim * @file
58234285Sdim * @brief This file contains all of the method implementations that
59234285Sdim *        can be utilized by a user to perform SCSI-to-ATA Translation.
60234285Sdim *        SATI adheres to the www.t10.org SAT specification.
61234285Sdim *
62234285Sdim * For situations where compliance is not observed, the SATI will
63234285Sdim * return an error indication (most likely INVALID FIELD IN CDB sense data).
64234285Sdim */
65234285Sdim
66234285Sdim#include <dev/isci/scil/sati.h>
67234285Sdim#include <dev/isci/scil/sati_callbacks.h>
68234285Sdim#include <dev/isci/scil/sati_util.h>
69234285Sdim#include <dev/isci/scil/sati_report_luns.h>
70234285Sdim#include <dev/isci/scil/sati_inquiry.h>
71234285Sdim#include <dev/isci/scil/sati_mode_sense_6.h>
72234285Sdim#include <dev/isci/scil/sati_mode_sense_10.h>
73234285Sdim#include <dev/isci/scil/sati_mode_select.h>
74234285Sdim#include <dev/isci/scil/sati_test_unit_ready.h>
75234285Sdim#include <dev/isci/scil/sati_read_capacity.h>
76234285Sdim#include <dev/isci/scil/sati_read.h>
77234285Sdim#include <dev/isci/scil/sati_write.h>
78234285Sdim#include <dev/isci/scil/sati_verify.h>
79234285Sdim#include <dev/isci/scil/sati_synchronize_cache.h>
80234285Sdim#include <dev/isci/scil/sati_lun_reset.h>
81234285Sdim#include <dev/isci/scil/sati_start_stop_unit.h>
82234285Sdim#include <dev/isci/scil/sati_request_sense.h>
83234285Sdim#include <dev/isci/scil/sati_write_long.h>
84234285Sdim#include <dev/isci/scil/sati_reassign_blocks.h>
85234285Sdim#include <dev/isci/scil/sati_log_sense.h>
86234285Sdim#include <dev/isci/scil/sati_abort_task_set.h>
87234285Sdim#include <dev/isci/scil/sati_unmap.h>
88234285Sdim#include <dev/isci/scil/sati_passthrough.h>
89234285Sdim#include <dev/isci/scil/sati_write_and_verify.h>
90234285Sdim#include <dev/isci/scil/sati_read_buffer.h>
91234285Sdim#include <dev/isci/scil/sati_write_buffer.h>
92234285Sdim#include <dev/isci/scil/intel_ata.h>
93234285Sdim#include <dev/isci/scil/intel_scsi.h>
94234285Sdim#include <dev/isci/scil/intel_sat.h>
95234285Sdim
96234285Sdim//******************************************************************************
97234285Sdim//* P R I V A T E   M E T H O D S
98234285Sdim//******************************************************************************
99234285Sdim
100234285Sdim/**
101234285Sdim * @brief This method performs the translation of ATA error register values
102234285Sdim *        into SCSI sense data.
103234285Sdim *        For more information on the parameter passed to this method please
104234285Sdim *        reference the sati_translate_response() method.
105234285Sdim *
106234285Sdim * @param[in] error This parameter specifies the contents of the ATA error
107234285Sdim *            register to be translated.
108234285Sdim *
109234285Sdim * @return none
110234285Sdim */
111234285Sdimvoid sati_translate_error(
112234285Sdim   SATI_TRANSLATOR_SEQUENCE_T * sequence,
113234285Sdim   void                       * scsi_io,
114234285Sdim   U8                           error
115234285Sdim)
116234285Sdim{
117234285Sdim   if (error & ATA_ERROR_REG_NO_MEDIA_BIT)
118234285Sdim   {
119234285Sdim      sati_scsi_sense_data_construct(
120234285Sdim         sequence,
121234285Sdim         scsi_io,
122234285Sdim         SCSI_STATUS_CHECK_CONDITION,
123234285Sdim         SCSI_SENSE_NOT_READY,
124234285Sdim         SCSI_ASC_MEDIUM_NOT_PRESENT,
125234285Sdim         SCSI_ASCQ_MEDIUM_NOT_PRESENT
126234285Sdim      );
127234285Sdim   }
128234285Sdim   else if (error & ATA_ERROR_REG_MEDIA_CHANGE_BIT)
129234285Sdim   {
130234285Sdim      sati_scsi_sense_data_construct(
131234285Sdim         sequence,
132234285Sdim         scsi_io,
133234285Sdim         SCSI_STATUS_CHECK_CONDITION,
134234285Sdim         SCSI_SENSE_UNIT_ATTENTION,
135234285Sdim         SCSI_ASC_NOT_READY_TO_READY_CHANGE,
136234285Sdim         SCSI_ASCQ_NOT_READY_TO_READY_CHANGE
137234285Sdim      );
138234285Sdim   }
139234285Sdim   else if (error & ATA_ERROR_REG_MEDIA_CHANGE_REQUEST_BIT)
140234285Sdim   {
141234285Sdim      sati_scsi_sense_data_construct(
142234285Sdim         sequence,
143234285Sdim         scsi_io,
144234285Sdim         SCSI_STATUS_CHECK_CONDITION,
145234285Sdim         SCSI_SENSE_UNIT_ATTENTION,
146234285Sdim         SCSI_ASC_MEDIUM_REMOVAL_REQUEST,
147234285Sdim         SCSI_ASCQ_MEDIUM_REMOVAL_REQUEST
148234285Sdim      );
149234285Sdim   }
150234285Sdim   else if (error & ATA_ERROR_REG_ID_NOT_FOUND_BIT)
151234285Sdim   {
152234285Sdim      sati_scsi_sense_data_construct(
153234285Sdim         sequence,
154234285Sdim         scsi_io,
155234285Sdim         SCSI_STATUS_CHECK_CONDITION,
156234285Sdim         SCSI_SENSE_ILLEGAL_REQUEST,
157234285Sdim         SCSI_ASC_LBA_OUT_OF_RANGE,
158234285Sdim         SCSI_ASCQ_LBA_OUT_OF_RANGE
159234285Sdim      );
160234285Sdim   }
161234285Sdim   else if (error & ATA_ERROR_REG_UNCORRECTABLE_BIT)
162234285Sdim   {
163234285Sdim      //Mark the Sequence state as a read error so more sense data
164234285Sdim      //can be returned later
165234285Sdim      sequence->state = SATI_SEQUENCE_STATE_READ_ERROR;
166234285Sdim      sati_scsi_sense_data_construct(
167234285Sdim         sequence,
168234285Sdim         scsi_io,
169234285Sdim         SCSI_STATUS_CHECK_CONDITION,
170234285Sdim         SCSI_SENSE_MEDIUM_ERROR,
171234285Sdim         SCSI_ASC_UNRECOVERED_READ_ERROR,
172234285Sdim         SCSI_ASCQ_UNRECOVERED_READ_ERROR
173234285Sdim      );
174234285Sdim   }
175234285Sdim   else if (  (sequence->data_direction == SATI_DATA_DIRECTION_OUT)
176234285Sdim           && (error & ATA_ERROR_REG_WRITE_PROTECTED_BIT) )
177234285Sdim   {
178234285Sdim      sati_scsi_sense_data_construct(
179234285Sdim         sequence,
180234285Sdim         scsi_io,
181234285Sdim         SCSI_STATUS_CHECK_CONDITION,
182234285Sdim         SCSI_SENSE_DATA_PROTECT,
183234285Sdim         SCSI_ASC_WRITE_PROTECTED,
184234982Sdim         SCSI_ASCQ_WRITE_PROTECTED
185234982Sdim      );
186234982Sdim   }
187234982Sdim   else if (error & ATA_ERROR_REG_ICRC_BIT)
188234982Sdim   {
189234982Sdim      sati_scsi_sense_data_construct(
190234982Sdim         sequence,
191234285Sdim         scsi_io,
192234285Sdim         SCSI_STATUS_CHECK_CONDITION,
193234285Sdim         SCSI_SENSE_ABORTED_COMMAND,
194234285Sdim         SCSI_ASC_IU_CRC_ERROR_DETECTED,
195234285Sdim         SCSI_ASCQ_IU_CRC_ERROR_DETECTED
196234285Sdim      );
197234285Sdim   }
198234285Sdim   else // (error & ATA_ERROR_REG_ABORT_BIT)
199234285Sdim   {
200234285Sdim      // The ABORT bit has the lowest precedence of all errors.
201234285Sdim      // As a result, it is at the bottom of the conditional
202234285Sdim      // statement.
203234285Sdim      sati_scsi_sense_data_construct(
204234285Sdim         sequence,
205234285Sdim         scsi_io,
206234285Sdim         SCSI_STATUS_CHECK_CONDITION,
207234285Sdim         SCSI_SENSE_ABORTED_COMMAND,
208234285Sdim         SCSI_ASC_NO_ADDITIONAL_SENSE,
209234285Sdim         SCSI_ASCQ_NO_ADDITIONAL_SENSE
210234285Sdim      );
211234285Sdim   }
212234285Sdim}
213234285Sdim
214234285Sdim/**
215234285Sdim * @brief This method translates the supplied ATA payload data into the
216234285Sdim *        corresponding SCSI data.  This is necessary for SCSI commands
217234285Sdim *        that have well-defined payload data associated with them (e.g.
218234285Sdim *        READ CAPACITY).
219234285Sdim *
220234285Sdim * @param[in]  sequence This parameter specifies the sequence
221234285Sdim *             data associated with the translation.
222234285Sdim * @param[in]  ata_io This parameter specifies the ATA payload
223234285Sdim *             buffer location and size to be translated.
224234285Sdim * @param[out] scsi_output_data This parameter specifies the SCSI payload
225234285Sdim *             memory area into which the translator is to write.
226234285Sdim *
227234285Sdim * @return none
228234285Sdim */
229234285Sdimstatic
230234285Sdimvoid sati_translate_data(
231234285Sdim   SATI_TRANSLATOR_SEQUENCE_T * sequence,
232234285Sdim   void                       * ata_input_data,
233234285Sdim   void                       * scsi_io
234234285Sdim)
235234285Sdim{
236234285Sdim   // Update the device capabilities in the odd/crazy event something changed.
237234285Sdim   sati_device_update_capabilities(
238234285Sdim      sequence->device, (ATA_IDENTIFY_DEVICE_DATA_T*) ata_input_data
239234285Sdim   );
240234285Sdim
241234285Sdim   // Look at the first byte to determine the SCSI command to translate.
242234285Sdim   switch (sequence->type)
243234285Sdim   {
244234285Sdim#if !defined(DISABLE_SATI_INQUIRY)
245234285Sdim      case SATI_SEQUENCE_INQUIRY_STANDARD:
246234285Sdim         sati_inquiry_standard_translate_data(
247234285Sdim            sequence, ata_input_data, scsi_io
248234285Sdim         );
249234285Sdim      break;
250234285Sdim
251234285Sdim      case SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER:
252234285Sdim         sati_inquiry_serial_number_translate_data(
253234285Sdim            sequence, ata_input_data, scsi_io
254234285Sdim         );
255234285Sdim      break;
256234285Sdim
257234285Sdim      case SATI_SEQUENCE_INQUIRY_DEVICE_ID:
258234285Sdim         sati_inquiry_device_id_translate_data(
259234285Sdim            sequence, ata_input_data, scsi_io
260234285Sdim         );
261234285Sdim      break;
262234285Sdim
263234285Sdim      case SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE:
264234285Sdim         sati_inquiry_block_device_translate_data(
265234285Sdim            sequence, ata_input_data, scsi_io
266234285Sdim         );
267234285Sdim      break;
268234285Sdim
269234285Sdim      case SATI_SEQUENCE_INQUIRY_ATA_INFORMATION:
270234285Sdim         sati_inquiry_ata_information_translate_data(
271234285Sdim            sequence, ata_input_data, scsi_io
272234285Sdim         );
273234285Sdim      break;
274234285Sdim
275234285Sdim#endif // !defined(DISABLE_SATI_INQUIRY)
276234285Sdim
277234285Sdim#if !defined(DISABLE_SATI_READ_CAPACITY)
278234285Sdim      case SATI_SEQUENCE_READ_CAPACITY_10:
279234285Sdim         sati_read_capacity_10_translate_data(sequence, ata_input_data, scsi_io);
280234285Sdim      break;
281234285Sdim
282234285Sdim      case SATI_SEQUENCE_READ_CAPACITY_16:
283234285Sdim         sati_read_capacity_16_translate_data(sequence, ata_input_data, scsi_io);
284234285Sdim      break;
285234285Sdim#endif // !defined(DISABLE_SATI_READ_CAPACITY)
286234285Sdim
287234285Sdim#if !defined(DISABLE_SATI_MODE_SENSE)
288234285Sdim      case SATI_SEQUENCE_MODE_SENSE_6_CACHING:
289234285Sdim         sati_mode_sense_6_caching_translate_data(
290234285Sdim            sequence, ata_input_data, scsi_io
291234285Sdim         );
292234285Sdim      break;
293234285Sdim
294234285Sdim      case SATI_SEQUENCE_MODE_SENSE_6_INFORMATIONAL_EXCP_CONTROL:
295234285Sdim         sati_mode_sense_6_informational_excp_control_translate_data(
296234285Sdim            sequence, ata_input_data, scsi_io
297234285Sdim         );
298234285Sdim      break;
299234285Sdim
300234285Sdim      case SATI_SEQUENCE_MODE_SENSE_6_READ_WRITE_ERROR:
301234285Sdim         sati_mode_sense_6_read_write_error_translate_data(
302234285Sdim            sequence, ata_input_data, scsi_io
303234285Sdim         );
304234285Sdim      break;
305234285Sdim
306234285Sdim      case SATI_SEQUENCE_MODE_SENSE_6_DISCONNECT_RECONNECT:
307234285Sdim         sati_mode_sense_6_disconnect_reconnect_translate_data(
308234285Sdim            sequence, ata_input_data, scsi_io
309234285Sdim         );
310234285Sdim      break;
311234285Sdim
312234285Sdim      case SATI_SEQUENCE_MODE_SENSE_6_CONTROL:
313234285Sdim         sati_mode_sense_6_control_translate_data(
314234285Sdim            sequence, ata_input_data, scsi_io
315234285Sdim         );
316234285Sdim      break;
317234285Sdim
318234285Sdim      case SATI_SEQUENCE_MODE_SENSE_6_ALL_PAGES:
319234285Sdim         sati_mode_sense_6_all_pages_translate_data(
320234285Sdim            sequence, ata_input_data, scsi_io
321234285Sdim         );
322234285Sdim      break;
323234285Sdim
324234285Sdim      case SATI_SEQUENCE_MODE_SENSE_6_POWER_CONDITION:
325234285Sdim         sati_mode_sense_6_power_condition_translate_data(
326234285Sdim            sequence, ata_input_data, scsi_io
327234285Sdim         );
328234285Sdim      break;
329234285Sdim
330234285Sdim      case SATI_SEQUENCE_MODE_SENSE_10_POWER_CONDITION:
331234285Sdim         sati_mode_sense_10_power_condition_translate_data(
332234285Sdim            sequence, ata_input_data, scsi_io
333234285Sdim         );
334234285Sdim      break;
335234285Sdim
336234285Sdim      case SATI_SEQUENCE_MODE_SENSE_10_CACHING:
337234285Sdim         sati_mode_sense_10_caching_translate_data(
338234285Sdim            sequence, ata_input_data, scsi_io
339234285Sdim         );
340234285Sdim      break;
341234285Sdim
342234285Sdim      case SATI_SEQUENCE_MODE_SENSE_10_INFORMATIONAL_EXCP_CONTROL:
343234285Sdim         sati_mode_sense_10_informational_excp_control_translate_data(
344234285Sdim            sequence, ata_input_data, scsi_io
345234285Sdim         );
346234285Sdim      break;
347234285Sdim
348234285Sdim      case SATI_SEQUENCE_MODE_SENSE_10_READ_WRITE_ERROR:
349234285Sdim         sati_mode_sense_10_read_write_error_translate_data(
350234285Sdim            sequence, ata_input_data, scsi_io
351234285Sdim         );
352      break;
353
354      case SATI_SEQUENCE_MODE_SENSE_10_DISCONNECT_RECONNECT:
355         sati_mode_sense_10_disconnect_reconnect_translate_data(
356            sequence, ata_input_data, scsi_io
357         );
358      break;
359
360      case SATI_SEQUENCE_MODE_SENSE_10_CONTROL:
361         sati_mode_sense_10_control_translate_data(
362            sequence, ata_input_data, scsi_io
363         );
364      break;
365
366      case SATI_SEQUENCE_MODE_SENSE_10_ALL_PAGES:
367         sati_mode_sense_10_all_pages_translate_data(
368            sequence, ata_input_data, scsi_io
369         );
370      break;
371#endif // !defined(DISABLE_SATI_MODE_SENSE)
372
373      default:
374      break;
375   }
376}
377
378//******************************************************************************
379//* P U B L I C   M E T H O D S
380//******************************************************************************
381
382SATI_STATUS sati_translate_command(
383   SATI_TRANSLATOR_SEQUENCE_T * sequence,
384   SATI_DEVICE_T              * sati_device,
385   void                       * scsi_io,
386   void                       * ata_io
387)
388{
389   SATI_STATUS   status = SATI_FAILURE;
390   U8          * cdb = sati_cb_get_cdb_address(scsi_io);
391
392   //No sense response has been set for the translation sequence yet
393   sequence->is_sense_response_set          = FALSE;
394   // Default to no translation response required
395   sequence->is_translate_response_required = FALSE;
396   // Assign sati_device to sequence
397   sequence->device  = sati_device;
398
399   /**
400    * Fail any I/O request with LUN != 0
401    */
402   if (sati_cb_get_lun(scsi_io) != 0)
403   {
404      sati_scsi_sense_data_construct(
405         sequence,
406         scsi_io,
407         SCSI_STATUS_CHECK_CONDITION,
408         SCSI_SENSE_ILLEGAL_REQUEST,
409         SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED,
410         0
411      );
412      return SATI_FAILURE_CHECK_RESPONSE_DATA;
413   }
414
415   /**
416    * SAT dictates:
417    * - the NACA bit in the control byte (last byte) must be 0
418    */
419   if ( (sati_get_cdb_byte(cdb, sati_cb_get_cdb_length(scsi_io) - 1)
420         & SCSI_CONTROL_BYTE_NACA_BIT_ENABLE))
421   {
422      sati_scsi_sense_data_construct(
423         sequence,
424         scsi_io,
425         SCSI_STATUS_CHECK_CONDITION,
426         SCSI_SENSE_ILLEGAL_REQUEST,
427         SCSI_ASC_INVALID_FIELD_IN_CDB,
428         SCSI_ASCQ_INVALID_FIELD_IN_CDB
429      );
430      return SATI_FAILURE_CHECK_RESPONSE_DATA;
431   }
432
433   /**
434    * Per SAT "Error and sense reporting" section.  All subsequent IOs after
435    * a device fault should receive INTERNAL TARGET FAILURE sense data.
436    */
437   if (sati_device->state == SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED)
438   {
439      sati_scsi_sense_data_construct(
440         sequence,
441         scsi_io,
442         SCSI_STATUS_CHECK_CONDITION,
443         SCSI_SENSE_HARDWARE_ERROR,
444         SCSI_ASC_INTERNAL_TARGET_FAILURE,
445         SCSI_ASCQ_INTERNAL_TARGET_FAILURE
446      );
447      return SATI_FAILURE_CHECK_RESPONSE_DATA;
448   }
449
450   if(sequence->state == SATI_SEQUENCE_STATE_INITIAL)
451   {
452      sequence->command_specific_data.scratch = 0;
453      sequence->number_data_bytes_set = 0;
454   }
455
456
457#ifdef SATI_TRANSPORT_SUPPORTS_SATA
458   {
459      U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
460      sati_set_sata_command_flag(register_fis);
461      sati_set_sata_fis_type(register_fis, SATA_FIS_TYPE_REGH2D);
462   }
463#endif // SATI_TRANSPORT_SUPPORTS_SATA
464
465   // Look at the first byte to determine the SCSI command to translate.
466   switch (sati_get_cdb_byte(cdb, 0))
467   {
468#if !defined(DISABLE_SATI_REPORT_LUNS)
469      case SCSI_REPORT_LUNS:
470         status = sati_report_luns_translate_command(
471                     sequence, scsi_io, ata_io
472                  );
473      break;
474#endif // !defined(DISABLE_SATI_REPORT_LUNS)
475
476#if !defined(DISABLE_SATI_INQUIRY)
477      case SCSI_INQUIRY:
478         status = sati_inquiry_translate_command(
479                     sequence, scsi_io, ata_io
480                  );
481      break;
482#endif // !defined(DISABLE_SATI_INQUIRY)
483
484#if !defined(DISABLE_SATI_MODE_SENSE)
485      case SCSI_MODE_SENSE_6:
486         status = sati_mode_sense_6_translate_command(
487                     sequence, scsi_io, ata_io
488                  );
489      break;
490
491      case SCSI_MODE_SENSE_10:
492         status = sati_mode_sense_10_translate_command(
493                     sequence, scsi_io, ata_io
494                  );
495      break;
496#endif // !defined(DISABLE_SATI_MODE_SENSE)
497
498#if !defined(DISABLE_SATI_MODE_SELECT)
499      case SCSI_MODE_SELECT_6:
500         status = sati_mode_select_6_translate_command(
501                     sequence, scsi_io, ata_io
502                  );
503      break;
504
505      case SCSI_MODE_SELECT_10:
506         status = sati_mode_select_10_translate_command(
507                     sequence, scsi_io, ata_io
508                  );
509      break;
510#endif // !defined(DISABLE_SATI_MODE_SELECT)
511
512#if !defined(DISABLE_SATI_TEST_UNIT_READY)
513      case SCSI_TEST_UNIT_READY:
514         status = sati_test_unit_ready_translate_command(
515                     sequence, scsi_io, ata_io
516                  );
517      break;
518#endif // !defined(DISABLE_SATI_TEST_UNIT_READY)
519
520#if !defined(DISABLE_SATI_READ_CAPACITY)
521      case SCSI_READ_CAPACITY_10:
522         status = sati_read_capacity_10_translate_command(
523                     sequence, scsi_io, ata_io
524                  );
525      break;
526
527      case SCSI_SERVICE_ACTION_IN_16:
528         if ( (sati_get_cdb_byte(cdb, 1) & SCSI_SERVICE_ACTION_MASK)
529              == SCSI_SERVICE_ACTION_IN_CODES_READ_CAPACITY_16)
530            status = sati_read_capacity_16_translate_command(
531                        sequence, scsi_io, ata_io
532                     );
533         else
534            status = SATI_FAILURE_CHECK_RESPONSE_DATA;
535      break;
536#endif // !defined(DISABLE_SATI_READ_CAPACITY)
537
538#if !defined(DISABLE_SATI_REQUEST_SENSE)
539      case SCSI_REQUEST_SENSE:
540         status = sati_request_sense_translate_command(
541                     sequence, scsi_io, ata_io
542                  );
543      break;
544#endif // !defined(DISABLE_SATI_REQUEST_SENSE)
545
546      case SCSI_READ_6:
547         status = sati_read_6_translate_command(sequence, scsi_io, ata_io);
548      break;
549
550      case SCSI_READ_10:
551         status = sati_read_10_translate_command(sequence, scsi_io, ata_io);
552      break;
553
554      case SCSI_READ_12:
555         status = sati_read_12_translate_command(sequence, scsi_io, ata_io);
556      break;
557
558      case SCSI_READ_16:
559         status = sati_read_16_translate_command(sequence, scsi_io, ata_io);
560      break;
561
562      case SCSI_WRITE_6:
563         status = sati_write_6_translate_command(sequence, scsi_io, ata_io);
564      break;
565
566      case SCSI_WRITE_10:
567         status = sati_write_10_translate_command(sequence, scsi_io, ata_io);
568      break;
569
570      case SCSI_WRITE_12:
571         status = sati_write_12_translate_command(sequence, scsi_io, ata_io);
572      break;
573
574      case SCSI_WRITE_16:
575         status = sati_write_16_translate_command(sequence, scsi_io, ata_io);
576      break;
577
578#if !defined(DISABLE_SATI_VERIFY)
579      case SCSI_VERIFY_10:
580         status = sati_verify_10_translate_command(sequence, scsi_io, ata_io);
581      break;
582
583      case SCSI_VERIFY_12:
584         status = sati_verify_12_translate_command(sequence, scsi_io, ata_io);
585      break;
586
587      case SCSI_VERIFY_16:
588         status = sati_verify_16_translate_command(sequence, scsi_io, ata_io);
589      break;
590#endif // !defined(DISABLE_SATI_VERIFY)
591
592#if    !defined(DISABLE_SATI_WRITE_AND_VERIFY)  \
593   && !defined(DISABLE_SATI_VERIFY)        \
594   && !defined(DISABLE_SATI_WRITE)
595
596      case SCSI_WRITE_AND_VERIFY_10:
597         status = sati_write_and_verify_10_translate_command(sequence, scsi_io, ata_io);
598      break;
599
600      case SCSI_WRITE_AND_VERIFY_12:
601         status = sati_write_and_verify_12_translate_command(sequence, scsi_io, ata_io);
602      break;
603
604      case SCSI_WRITE_AND_VERIFY_16:
605         status = sati_write_and_verify_16_translate_command(sequence, scsi_io, ata_io);
606      break;
607#endif //    !defined(DISABLE_SATI_WRITE_AND_VERIFY)
608      // && !defined(DISABLE_SATI_VERIFY)
609      // && !defined(DISABLE_SATI_WRITE)
610
611#if !defined(DISABLE_SATI_REASSIGN_BLOCKS)
612      case SCSI_REASSIGN_BLOCKS:
613         status = sati_reassign_blocks_translate_command(sequence, scsi_io, ata_io);
614      break;
615#endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
616
617#if !defined(DISABLE_SATI_SYNCHRONIZE_CACHE)
618      case SCSI_SYNCHRONIZE_CACHE_10:
619      case SCSI_SYNCHRONIZE_CACHE_16:
620         status = sati_synchronize_cache_translate_command(sequence, scsi_io, ata_io);
621      break;
622#endif // !defined(DISABLE_SATI_SYNCHRONIZE_CACHE)
623
624#if !defined(DISABLE_SATI_START_STOP_UNIT)
625      case SCSI_START_STOP_UNIT:
626         status = sati_start_stop_unit_translate_command(
627                     sequence, scsi_io, ata_io
628                  );
629      break;
630#endif // !defined(DISABLE_SATI_START_STOP_UNIT)
631
632#if !defined(DISABLE_SATI_WRITE_LONG)
633      case SCSI_WRITE_LONG_10:
634      case SCSI_WRITE_LONG_16:
635         status = sati_write_long_translate_command(sequence, scsi_io, ata_io);
636      break;
637#endif // !defined(DISABLE_SATI_WRITE_LONG)
638
639#if !defined(DISABLE_SATI_LOG_SENSE)
640      case SCSI_LOG_SENSE:
641         status = sati_log_sense_translate_command(sequence, scsi_io, ata_io);
642      break;
643#endif // !defined(DISABLE_SATI_LOG_SENSE)
644
645      case SCSI_PERSISTENT_RESERVE_IN:
646      case SCSI_PERSISTENT_RESERVE_OUT:
647         //These commands are not supported by SATI
648         sati_scsi_sense_data_construct(
649            sequence,
650            scsi_io,
651            SCSI_STATUS_CHECK_CONDITION,
652            SCSI_SENSE_ILLEGAL_REQUEST,
653            SCSI_ASC_INVALID_COMMAND_OPERATION_CODE,
654            SCSI_ASCQ_INVALID_COMMAND_OPERATION_CODE
655         );
656         //returning status now to keep sense data set above
657         return SATI_FAILURE_CHECK_RESPONSE_DATA;
658      break;
659
660#if !defined(DISABLE_SATI_UNMAP)
661      case SCSI_UNMAP:
662         status = sati_unmap_translate_command(sequence, scsi_io, ata_io);
663      break;
664#endif // !defined(DISABLE_SATI_UNMAP)
665
666#if !defined(DISABLE_SATI_ATA_PASSTHROUGH)
667      case SCSI_ATA_PASSTHRU_12:
668          status = sati_passthrough_12_translate_command(sequence, scsi_io, ata_io);
669      break;
670
671      case SCSI_ATA_PASSTHRU_16:
672          status = sati_passthrough_16_translate_command(sequence, scsi_io, ata_io);
673      break;
674
675#endif // !define(DISABLE_SATI_ATA_PASSTHRU)
676
677#if !defined(DISABLE_SATI_READ_BUFFER)
678      case SCSI_READ_BUFFER:
679         status = sati_read_buffer_translate_command(sequence, scsi_io, ata_io);
680      break;
681#endif //!defined(DISABLE_SATI_READ_BUFFER)
682
683#if !defined(DISABLE_SATI_WRITE_BUFFER)
684      case SCSI_WRITE_BUFFER:
685         status = sati_write_buffer_translate_command(sequence, scsi_io, ata_io);
686      break;
687#endif //!defined(DISABLE_SATI_WRITE_BUFFER)
688      default:
689         status = SATI_FAILURE_CHECK_RESPONSE_DATA;
690      break;
691   }
692
693   if( (status == SATI_FAILURE_CHECK_RESPONSE_DATA) &&
694       !(sequence->is_sense_response_set) )
695   {
696      sati_scsi_sense_data_construct(
697         sequence,
698         scsi_io,
699         SCSI_STATUS_CHECK_CONDITION,
700         SCSI_SENSE_ILLEGAL_REQUEST,
701         SCSI_ASC_INVALID_FIELD_IN_CDB,
702         SCSI_ASCQ_INVALID_FIELD_IN_CDB
703      );
704   }
705   return status;
706}
707
708// -----------------------------------------------------------------------------
709
710#if !defined(DISABLE_SATI_TASK_MANAGEMENT)
711SATI_STATUS sati_translate_task_management(
712   SATI_TRANSLATOR_SEQUENCE_T * sequence,
713   SATI_DEVICE_T              * sati_device,
714   void                       * scsi_task,
715   void                       * ata_io
716)
717{
718   SATI_STATUS status=SATI_FAILURE;
719   U8 task_function = sati_cb_get_task_function(scsi_task);
720
721   sequence->device = sati_device;
722
723   switch (task_function)
724   {
725      /**
726       * @todo We need to update the ABORT_TASK and ABORT_TASK_SET to be
727       *       SAT compliant.
728       */
729      case SCSI_TASK_REQUEST_ABORT_TASK:
730      case SCSI_TASK_REQUEST_LOGICAL_UNIT_RESET:
731         status = sati_lun_reset_translate_command(sequence, scsi_task, ata_io);
732      break;
733
734      case SCSI_TASK_REQUEST_ABORT_TASK_SET:
735#if !defined(DISABLE_SATI_ABORT_TASK_SET)
736         status = sati_abort_task_set_translate_command(sequence, scsi_task, ata_io);
737#else
738         status = SATI_FAILURE;
739#endif
740         break;
741      default:
742         status = SATI_FAILURE;
743      break;
744   }
745
746   return status;
747}
748#endif // !defined(DISABLE_SATI_TASK_MANAGEMENT)
749
750// -----------------------------------------------------------------------------
751#if      !defined(DISABLE_SATI_INQUIRY)            \
752      || !defined(DISABLE_SATI_READY_CAPACITY)     \
753      || !defined(DISABLE_SATI_MODE_SENSE)         \
754      || !defined(DISABLE_SATI_MODE_SELECT)        \
755      || !defined(DISABLE_SATI_REASSIGN_BLOCKS)    \
756      || !defined(DISABLE_SATI_START_STOP_UNIT)    \
757      || !defined(DISABLE_SATI_REQUEST_SENSE)      \
758      || !defined(DISABLE_SATI_WRITE_LONG)         \
759      || !defined(DISABLE_SATI_LOG_SENSE)          \
760      || !defined(DISABLE_SATI_UNMAP)
761
762static
763SATI_STATUS sati_check_data_io(
764   SATI_TRANSLATOR_SEQUENCE_T * sequence
765)
766{
767   if(sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE)
768   {
769      return SATI_SEQUENCE_INCOMPLETE;
770   }
771   else if(sequence->number_data_bytes_set < sequence->allocation_length)
772   {
773      return SATI_COMPLETE_IO_DONE_EARLY;
774   }
775   else
776   {
777      return SATI_COMPLETE;
778   }
779}
780#endif   //    !defined(DISABLE_SATI_INQUIRY)
781         // || !defined(DISABLE_SATI_READY_CAPACITY)
782         // || !defined(DISABLE_SATI_MODE_SENSE)
783         // || !defined(DISABLE_SATI_MODE_SELECT)
784         // || !defined(DISABLE_SATI_REASSIGN_BLOCKS)
785         // || !defined(DISABLE_SATI_START_STOP_UNIT)
786         // || !defined(DISABLE_SATI_REQUEST_SENSE)
787         // || !defined(DISABLE_SATI_WRITE_LONG)
788         // || !defined(DISABLE_SATI_LOG_SENSE)
789         // || !defined(DISABLE_SATI_UNMAP)
790// -----------------------------------------------------------------------------
791SATI_STATUS sati_translate_command_response(
792   SATI_TRANSLATOR_SEQUENCE_T * sequence,
793   void                       * scsi_io,
794   void                       * ata_io
795)
796{
797   SATI_STATUS   status       = SATI_COMPLETE;
798   U8          * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
799   U8            ata_status;
800
801   /**
802    * If the device fault bit is set in the status register, then
803    * set the sense data and return.
804    */
805   ata_status = (U8) sati_get_ata_status(register_fis);
806   if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT)
807   {
808      sati_scsi_sense_data_construct(
809         sequence,
810         scsi_io,
811         SCSI_STATUS_CHECK_CONDITION,
812         SCSI_SENSE_HARDWARE_ERROR,
813         SCSI_ASC_INTERNAL_TARGET_FAILURE,
814         SCSI_ASCQ_INTERNAL_TARGET_FAILURE
815      );
816
817      sequence->device->state = SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED;
818
819      // Make sure that the terminate sequence is called to allow
820      // translation logic to perform any cleanup before the IO is completed.
821      sati_sequence_terminate(sequence,
822                              scsi_io,
823                              ata_io);
824
825      return SATI_FAILURE_CHECK_RESPONSE_DATA;
826   }
827
828   // Look at the sequence type to determine the response translation method
829   // to invoke.
830   switch (sequence->type)
831   {
832#if !defined(DISABLE_SATI_TEST_UNIT_READY)
833      case SATI_SEQUENCE_TEST_UNIT_READY:
834         status = sati_test_unit_ready_translate_response(
835                     sequence, scsi_io, ata_io
836                  );
837      break;
838#endif // !defined(DISABLE_SATI_TEST_UNIT_READY)
839
840#if    !defined(DISABLE_SATI_INQUIRY)        \
841    || !defined(DISABLE_SATI_READY_CAPACITY) \
842    || !defined(DISABLE_SATI_MODE_SENSE)
843
844      case SATI_SEQUENCE_INQUIRY_EXECUTE_DEVICE_DIAG:
845
846         if (ata_status & ATA_STATUS_REG_ERROR_BIT)
847         {
848            U8  error = (U8) sati_get_ata_error(register_fis);
849            status    = SATI_FAILURE_CHECK_RESPONSE_DATA;
850            sati_translate_error(sequence, scsi_io, error);
851         }
852         else
853         {
854            sati_inquiry_ata_information_finish_translation(
855               sequence,
856               scsi_io,
857               ata_io
858            );
859            status = sati_check_data_io(sequence);
860         }
861      break;
862
863      case SATI_SEQUENCE_INQUIRY_STANDARD:
864      case SATI_SEQUENCE_INQUIRY_SUPPORTED_PAGES:
865      case SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER:
866      case SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE:
867      case SATI_SEQUENCE_INQUIRY_ATA_INFORMATION:
868      case SATI_SEQUENCE_INQUIRY_DEVICE_ID:
869      case SATI_SEQUENCE_READ_CAPACITY_10:
870      case SATI_SEQUENCE_READ_CAPACITY_16:
871      case SATI_SEQUENCE_MODE_SENSE_6_CACHING:
872      case SATI_SEQUENCE_MODE_SENSE_6_INFORMATIONAL_EXCP_CONTROL:
873      case SATI_SEQUENCE_MODE_SENSE_6_READ_WRITE_ERROR:
874      case SATI_SEQUENCE_MODE_SENSE_6_DISCONNECT_RECONNECT:
875      case SATI_SEQUENCE_MODE_SENSE_6_CONTROL:
876      case SATI_SEQUENCE_MODE_SENSE_6_POWER_CONDITION:
877      case SATI_SEQUENCE_MODE_SENSE_6_ALL_PAGES:
878      case SATI_SEQUENCE_MODE_SENSE_10_CACHING:
879      case SATI_SEQUENCE_MODE_SENSE_10_INFORMATIONAL_EXCP_CONTROL:
880      case SATI_SEQUENCE_MODE_SENSE_10_READ_WRITE_ERROR:
881      case SATI_SEQUENCE_MODE_SENSE_10_CONTROL:
882      case SATI_SEQUENCE_MODE_SENSE_10_POWER_CONDITION:
883      case SATI_SEQUENCE_MODE_SENSE_10_DISCONNECT_RECONNECT:
884      case SATI_SEQUENCE_MODE_SENSE_10_ALL_PAGES:
885         // Did an error occur during the IO request?
886         if (ata_status & ATA_STATUS_REG_ERROR_BIT)
887         {
888            U8  error = (U8) sati_get_ata_error(register_fis);
889            status    = SATI_FAILURE_CHECK_RESPONSE_DATA;
890            sati_translate_error(sequence, scsi_io, error);
891         }
892         else
893         {
894            void * ata_data = sati_cb_get_ata_data_address(ata_io);
895
896            if(ata_data == NULL)
897            {
898               status = SATI_FAILURE;
899            }
900            else
901            {
902               sati_translate_data(sequence, ata_data, scsi_io);
903               status = sati_check_data_io(sequence);
904            }
905         }
906      break;
907#endif //    !defined(DISABLE_SATI_INQUIRY)
908       // && !defined(DISABLE_SATI_READY_CAPACITY)
909       // && !defined(DISABLE_SATI_MODE_SENSE)
910
911#if !defined(DISABLE_SATI_MODE_SELECT)
912      case SATI_SEQUENCE_MODE_SELECT_MODE_PAGE_CACHING:
913
914         status = sati_mode_select_translate_response(
915            sequence, scsi_io, ata_io
916               );
917         if(status == SATI_COMPLETE)
918         {
919            status = sati_check_data_io(sequence);
920         }
921         break;
922
923      case SATI_SEQUENCE_MODE_SELECT_MODE_POWER_CONDITION:
924      case SATI_SEQUENCE_MODE_SELECT_MODE_INFORMATION_EXCEPT_CONTROL:
925         // Did an error occur during the IO request?
926         if (ata_status & ATA_STATUS_REG_ERROR_BIT)
927         {
928            U8  error = (U8) sati_get_ata_error(register_fis);
929            status    = SATI_FAILURE_CHECK_RESPONSE_DATA;
930            sati_translate_error(sequence, scsi_io, error);
931         }
932         else
933         {
934            status = sati_check_data_io(sequence);
935         }
936      break;
937#endif // !defined(DISABLE_SATI_MODE_SELECT)
938
939#if !defined(DISABLE_SATI_WRITE_AND_VERIFY)
940      case SATI_SEQUENCE_WRITE_AND_VERIFY:
941
942         if (ata_status & ATA_STATUS_REG_ERROR_BIT)
943         {
944            U8  error = (U8) sati_get_ata_error(register_fis);
945            sati_translate_error(sequence, scsi_io, error);
946
947            return SATI_FAILURE_CHECK_RESPONSE_DATA;
948         }
949         else
950         {
951            status = sati_write_and_verify_translate_response(
952                        sequence,
953                        scsi_io,
954                        ata_io
955                     );
956         }
957      break;
958#endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY)
959
960      case SATI_SEQUENCE_READ_6:
961      case SATI_SEQUENCE_READ_10:
962      case SATI_SEQUENCE_READ_12:
963      case SATI_SEQUENCE_READ_16:
964      case SATI_SEQUENCE_WRITE_6:
965      case SATI_SEQUENCE_WRITE_10:
966      case SATI_SEQUENCE_WRITE_12:
967      case SATI_SEQUENCE_WRITE_16:
968      case SATI_SEQUENCE_VERIFY_10:
969      case SATI_SEQUENCE_VERIFY_12:
970      case SATI_SEQUENCE_VERIFY_16:
971      case SATI_SEQUENCE_SYNCHRONIZE_CACHE:
972         if (ata_status & ATA_STATUS_REG_ERROR_BIT)
973         {
974            U8  error = (U8) sati_get_ata_error(register_fis);
975            status    = SATI_FAILURE_CHECK_RESPONSE_DATA;
976            sati_translate_error(sequence, scsi_io, error);
977
978            if(sequence->state == SATI_SEQUENCE_STATE_READ_ERROR )
979            {
980               sati_scsi_read_error_sense_construct(
981                  sequence,
982                  scsi_io,
983                  ata_io,
984                  SCSI_STATUS_CHECK_CONDITION,
985                  SCSI_SENSE_MEDIUM_ERROR,
986                  SCSI_ASC_UNRECOVERED_READ_ERROR,
987                  SCSI_ASCQ_UNRECOVERED_READ_ERROR
988               );
989               sequence->state = SATI_SEQUENCE_STATE_FINAL;
990            }
991         }
992         else
993         {
994            // We haven't satisified the transfer count from the original
995            // SCSI CDB.  As a result, we need to re-issue the command
996            // with updated logical block address and transfer count.
997            if (sequence->command_specific_data.scratch)
998            {
999               /** @todo update the contents of the CDB directly?  Should be
1000                *  done during previous command translation?
1001                */
1002               status = SATI_SEQUENCE_INCOMPLETE;
1003            }
1004         }
1005      break;
1006
1007#if !defined(DISABLE_SATI_READ_BUFFER)
1008      case SATI_SEQUENCE_READ_BUFFER:
1009         status = sati_read_buffer_translate_response(
1010                     sequence, scsi_io, ata_io
1011                  );
1012
1013         if(status == SATI_COMPLETE)
1014         {
1015            status = sati_check_data_io(sequence);
1016         }
1017      break;
1018#endif //!defined(DISABLE_SATI_READ_BUFFER)
1019
1020#if !defined(DISABLE_SATI_WRITE_BUFFER)
1021      case SATI_SEQUENCE_WRITE_BUFFER:
1022      case SATI_SEQUENCE_WRITE_BUFFER_MICROCODE:
1023         status = sati_write_buffer_translate_response(
1024                     sequence, scsi_io, ata_io
1025                  );
1026      break;
1027#endif //!defined(DISABLE_SATI_WRITE_BUFFER)
1028
1029#if !defined(DISABLE_SATI_REASSIGN_BLOCKS)
1030      case SATI_SEQUENCE_REASSIGN_BLOCKS:
1031         status = sati_reassign_blocks_translate_response(
1032                     sequence, scsi_io, ata_io
1033                  );
1034         if(status == SATI_COMPLETE)
1035         {
1036            status = sati_check_data_io(sequence);
1037         }
1038      break;
1039#endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
1040
1041#if !defined(DISABLE_SATI_START_STOP_UNIT)
1042      case SATI_SEQUENCE_START_STOP_UNIT:
1043         status = sati_start_stop_unit_translate_response(
1044                     sequence, scsi_io, ata_io
1045                  );
1046         if(status == SATI_COMPLETE)
1047         {
1048            status = sati_check_data_io(sequence);
1049         }
1050      break;
1051#endif // !defined(DISABLE_SATI_START_STOP_UNIT)
1052
1053#if !defined(DISABLE_SATI_REQUEST_SENSE)
1054      case SATI_SEQUENCE_REQUEST_SENSE_SMART_RETURN_STATUS:
1055      case SATI_SEQUENCE_REQUEST_SENSE_CHECK_POWER_MODE:
1056         status = sati_request_sense_translate_response(
1057                     sequence, scsi_io, ata_io
1058                  );
1059         if(status == SATI_COMPLETE)
1060         {
1061            status = sati_check_data_io(sequence);
1062         }
1063      break;
1064#endif // !defined(DISABLE_SATI_REQUEST_SENSE)
1065
1066#if !defined(DISABLE_SATI_WRITE_LONG)
1067      case SATI_SEQUENCE_WRITE_LONG:
1068         status = sati_write_long_translate_response(
1069                     sequence, scsi_io, ata_io
1070                  );
1071         if(status == SATI_COMPLETE)
1072         {
1073            status = sati_check_data_io(sequence);
1074         }
1075      break;
1076#endif // !defined(DISABLE_SATI_WRITE_LONG)
1077
1078#if !defined(DISABLE_SATI_LOG_SENSE)
1079      case SATI_SEQUENCE_LOG_SENSE_SUPPORTED_LOG_PAGE:
1080      case SATI_SEQUENCE_LOG_SENSE_SELF_TEST_LOG_PAGE:
1081      case SATI_SEQUENCE_LOG_SENSE_EXTENDED_SELF_TEST_LOG_PAGE:
1082      case SATI_SEQUENCE_LOG_SENSE_INFO_EXCEPTION_LOG_PAGE:
1083         status = sati_log_sense_translate_response(
1084                     sequence, scsi_io, ata_io
1085                  );
1086         if(status == SATI_COMPLETE)
1087         {
1088            status = sati_check_data_io(sequence);
1089         }
1090      break;
1091#endif // !defined(DISABLE_SATI_LOG_SENSE)
1092
1093#if !defined(DISABLE_SATI_UNMAP)
1094      case SATI_SEQUENCE_UNMAP:
1095         status = sati_unmap_translate_response(
1096                     sequence, scsi_io, ata_io
1097                  );
1098      break;
1099#endif // !defined(DISABLE_SATI_UNMAP)
1100
1101#if !defined(DISABLE_SATI_ATA_PASSTHROUGH)
1102      case SATI_SEQUENCE_ATA_PASSTHROUGH_12:
1103      case SATI_SEQUENCE_ATA_PASSTHROUGH_16:
1104         status = sati_passthrough_translate_response(
1105                     sequence, scsi_io, ata_io
1106                  );
1107      break;
1108#endif // !defined(DISABLE_SATI_ATA_PASSTHROUGH)
1109
1110      default:
1111         status = SATI_FAILURE_INVALID_SEQUENCE_TYPE;
1112      break;
1113   }
1114
1115   return status;
1116}
1117
1118// -----------------------------------------------------------------------------
1119
1120#if !defined(DISABLE_SATI_TASK_MANAGEMENT)
1121SATI_STATUS sati_translate_task_response(
1122   SATI_TRANSLATOR_SEQUENCE_T * sequence,
1123   void                       * scsi_io,
1124   void                       * ata_io
1125)
1126{
1127   SATI_STATUS   status       = SATI_FAILURE_CHECK_RESPONSE_DATA;
1128   U8          * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
1129   U8            ata_status;
1130
1131   /**
1132    * If the device fault bit is set in the status register, then
1133    * set the sense data and return.
1134    */
1135   ata_status = (U8) sati_get_ata_status(register_fis);
1136   if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT)
1137   {
1138      sati_scsi_response_data_construct(
1139         sequence,
1140         scsi_io,
1141         SCSI_TASK_MGMT_FUNC_FAILED
1142      );
1143      return SATI_FAILURE_CHECK_RESPONSE_DATA;
1144   }
1145
1146   // Look at the sequence type to determine the response translation method
1147   // to invoke.
1148   switch (sequence->type)
1149   {
1150      case SATI_SEQUENCE_LUN_RESET:
1151         if (ata_status & ATA_STATUS_REG_ERROR_BIT)
1152         {
1153            sati_scsi_response_data_construct(
1154               sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED);
1155         }
1156         else
1157         {
1158            sati_scsi_response_data_construct(
1159               sequence, scsi_io, SCSI_TASK_MGMT_FUNC_COMPLETE);
1160         }
1161
1162         status = SATI_COMPLETE;
1163      break;
1164
1165#if !defined(DISABLE_SATI_ABORT_TASK_SET)
1166      case SATI_SEQUENCE_ABORT_TASK_SET:
1167         if (ata_status & ATA_STATUS_REG_ERROR_BIT)
1168         {
1169            sati_scsi_response_data_construct(
1170               sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED);
1171         }
1172         else
1173         {
1174            void * ata_data = sati_cb_get_ata_data_address(ata_io);
1175
1176            if(ata_data == NULL)
1177            {
1178               status = SATI_FAILURE;
1179            }
1180            else
1181            {
1182               status = sati_abort_task_set_translate_data(
1183                           sequence,
1184                           ata_data,
1185                           scsi_io
1186                        );
1187            }
1188         }
1189      break;
1190#endif // !defined(DISABLE_SATI_ABORT_TASK_SET)
1191
1192      default:
1193         status = SATI_FAILURE_INVALID_SEQUENCE_TYPE;
1194      break;
1195   }
1196
1197   return status;
1198}
1199#endif // !defined(DISABLE_SATI_TASK_MANAGEMENT)
1200
1201#if !defined(ENABLE_MINIMUM_MEMORY_MODE)
1202U32 sati_get_sat_compliance_version(
1203   void
1204)
1205{
1206   return 2;  // Compliant with SAT-2.
1207}
1208
1209U32 sati_get_sat_compliance_version_revision(
1210   void
1211)
1212{
1213   return 7;  // Compliant with SAT-2 revision 7.
1214}
1215
1216#endif // !defined(ENABLE_MINIMUM_MEMORY_MODE)
1217
1218U16 sati_get_number_data_bytes_set(
1219   SATI_TRANSLATOR_SEQUENCE_T * sequence
1220)
1221{
1222   return sequence->number_data_bytes_set;
1223}
1224
1225void sati_sequence_construct(
1226   SATI_TRANSLATOR_SEQUENCE_T * sequence
1227)
1228{
1229   sequence->state = SATI_SEQUENCE_STATE_INITIAL;
1230}
1231
1232void sati_sequence_terminate(
1233   SATI_TRANSLATOR_SEQUENCE_T * sequence,
1234   void                       * scsi_io,
1235   void                       * ata_io
1236)
1237{
1238   // Decode the sequence type to determine how to handle the termination
1239   // of the translation method.
1240   switch (sequence->type)
1241   {
1242   case SATI_SEQUENCE_UNMAP:
1243      sati_unmap_terminate(sequence,scsi_io,ata_io);
1244   break;
1245   }
1246}
1247