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