1/*-
2 * This file is provided under a dual BSD/GPLv2 license.  When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 *   * Redistributions of source code must retain the above copyright
34 *     notice, this list of conditions and the following disclaimer.
35 *   * Redistributions in binary form must reproduce the above copyright
36 *     notice, this list of conditions and the following disclaimer in
37 *     the documentation and/or other materials provided with the
38 *     distribution.
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 */
52
53#include <sys/cdefs.h>
54__FBSDID("$FreeBSD$");
55
56/**
57 * @file
58 * @brief This file contains all of the method implementations that
59 *        can be utilized by a user to perform SCSI-to-ATA Translation.
60 *        SATI adheres to the www.t10.org SAT specification.
61 *
62 * For situations where compliance is not observed, the SATI will
63 * return an error indication (most likely INVALID FIELD IN CDB sense data).
64 */
65
66#include <dev/isci/scil/sati.h>
67#include <dev/isci/scil/sati_callbacks.h>
68#include <dev/isci/scil/sati_util.h>
69#include <dev/isci/scil/sati_report_luns.h>
70#include <dev/isci/scil/sati_inquiry.h>
71#include <dev/isci/scil/sati_mode_sense_6.h>
72#include <dev/isci/scil/sati_mode_sense_10.h>
73#include <dev/isci/scil/sati_mode_select.h>
74#include <dev/isci/scil/sati_test_unit_ready.h>
75#include <dev/isci/scil/sati_read_capacity.h>
76#include <dev/isci/scil/sati_read.h>
77#include <dev/isci/scil/sati_write.h>
78#include <dev/isci/scil/sati_verify.h>
79#include <dev/isci/scil/sati_synchronize_cache.h>
80#include <dev/isci/scil/sati_lun_reset.h>
81#include <dev/isci/scil/sati_start_stop_unit.h>
82#include <dev/isci/scil/sati_request_sense.h>
83#include <dev/isci/scil/sati_write_long.h>
84#include <dev/isci/scil/sati_reassign_blocks.h>
85#include <dev/isci/scil/sati_log_sense.h>
86#include <dev/isci/scil/sati_abort_task_set.h>
87#include <dev/isci/scil/sati_unmap.h>
88#include <dev/isci/scil/sati_passthrough.h>
89#include <dev/isci/scil/sati_write_and_verify.h>
90#include <dev/isci/scil/sati_read_buffer.h>
91#include <dev/isci/scil/sati_write_buffer.h>
92#include <dev/isci/scil/intel_ata.h>
93#include <dev/isci/scil/intel_scsi.h>
94#include <dev/isci/scil/intel_sat.h>
95
96//******************************************************************************
97//* P R I V A T E   M E T H O D S
98//******************************************************************************
99
100/**
101 * @brief This method performs the translation of ATA error register values
102 *        into SCSI sense data.
103 *        For more information on the parameter passed to this method please
104 *        reference the sati_translate_response() method.
105 *
106 * @param[in] error This parameter specifies the contents of the ATA error
107 *            register to be translated.
108 *
109 * @return none
110 */
111void sati_translate_error(
112   SATI_TRANSLATOR_SEQUENCE_T * sequence,
113   void                       * scsi_io,
114   U8                           error
115)
116{
117   if (error & ATA_ERROR_REG_NO_MEDIA_BIT)
118   {
119      sati_scsi_sense_data_construct(
120         sequence,
121         scsi_io,
122         SCSI_STATUS_CHECK_CONDITION,
123         SCSI_SENSE_NOT_READY,
124         SCSI_ASC_MEDIUM_NOT_PRESENT,
125         SCSI_ASCQ_MEDIUM_NOT_PRESENT
126      );
127   }
128   else if (error & ATA_ERROR_REG_MEDIA_CHANGE_BIT)
129   {
130      sati_scsi_sense_data_construct(
131         sequence,
132         scsi_io,
133         SCSI_STATUS_CHECK_CONDITION,
134         SCSI_SENSE_UNIT_ATTENTION,
135         SCSI_ASC_NOT_READY_TO_READY_CHANGE,
136         SCSI_ASCQ_NOT_READY_TO_READY_CHANGE
137      );
138   }
139   else if (error & ATA_ERROR_REG_MEDIA_CHANGE_REQUEST_BIT)
140   {
141      sati_scsi_sense_data_construct(
142         sequence,
143         scsi_io,
144         SCSI_STATUS_CHECK_CONDITION,
145         SCSI_SENSE_UNIT_ATTENTION,
146         SCSI_ASC_MEDIUM_REMOVAL_REQUEST,
147         SCSI_ASCQ_MEDIUM_REMOVAL_REQUEST
148      );
149   }
150   else if (error & ATA_ERROR_REG_ID_NOT_FOUND_BIT)
151   {
152      sati_scsi_sense_data_construct(
153         sequence,
154         scsi_io,
155         SCSI_STATUS_CHECK_CONDITION,
156         SCSI_SENSE_ILLEGAL_REQUEST,
157         SCSI_ASC_LBA_OUT_OF_RANGE,
158         SCSI_ASCQ_LBA_OUT_OF_RANGE
159      );
160   }
161   else if (error & ATA_ERROR_REG_UNCORRECTABLE_BIT)
162   {
163      //Mark the Sequence state as a read error so more sense data
164      //can be returned later
165      sequence->state = SATI_SEQUENCE_STATE_READ_ERROR;
166      sati_scsi_sense_data_construct(
167         sequence,
168         scsi_io,
169         SCSI_STATUS_CHECK_CONDITION,
170         SCSI_SENSE_MEDIUM_ERROR,
171         SCSI_ASC_UNRECOVERED_READ_ERROR,
172         SCSI_ASCQ_UNRECOVERED_READ_ERROR
173      );
174   }
175   else if (  (sequence->data_direction == SATI_DATA_DIRECTION_OUT)
176           && (error & ATA_ERROR_REG_WRITE_PROTECTED_BIT) )
177   {
178      sati_scsi_sense_data_construct(
179         sequence,
180         scsi_io,
181         SCSI_STATUS_CHECK_CONDITION,
182         SCSI_SENSE_DATA_PROTECT,
183         SCSI_ASC_WRITE_PROTECTED,
184         SCSI_ASCQ_WRITE_PROTECTED
185      );
186   }
187   else if (error & ATA_ERROR_REG_ICRC_BIT)
188   {
189      sati_scsi_sense_data_construct(
190         sequence,
191         scsi_io,
192         SCSI_STATUS_CHECK_CONDITION,
193         SCSI_SENSE_ABORTED_COMMAND,
194         SCSI_ASC_IU_CRC_ERROR_DETECTED,
195         SCSI_ASCQ_IU_CRC_ERROR_DETECTED
196      );
197   }
198   else // (error & ATA_ERROR_REG_ABORT_BIT)
199   {
200      // The ABORT bit has the lowest precedence of all errors.
201      // As a result, it is at the bottom of the conditional
202      // statement.
203      sati_scsi_sense_data_construct(
204         sequence,
205         scsi_io,
206         SCSI_STATUS_CHECK_CONDITION,
207         SCSI_SENSE_ABORTED_COMMAND,
208         SCSI_ASC_NO_ADDITIONAL_SENSE,
209         SCSI_ASCQ_NO_ADDITIONAL_SENSE
210      );
211   }
212}
213
214/**
215 * @brief This method translates the supplied ATA payload data into the
216 *        corresponding SCSI data.  This is necessary for SCSI commands
217 *        that have well-defined payload data associated with them (e.g.
218 *        READ CAPACITY).
219 *
220 * @param[in]  sequence This parameter specifies the sequence
221 *             data associated with the translation.
222 * @param[in]  ata_io This parameter specifies the ATA payload
223 *             buffer location and size to be translated.
224 * @param[out] scsi_output_data This parameter specifies the SCSI payload
225 *             memory area into which the translator is to write.
226 *
227 * @return none
228 */
229static
230void sati_translate_data(
231   SATI_TRANSLATOR_SEQUENCE_T * sequence,
232   void                       * ata_input_data,
233   void                       * scsi_io
234)
235{
236   // Update the device capabilities in the odd/crazy event something changed.
237   sati_device_update_capabilities(
238      sequence->device, (ATA_IDENTIFY_DEVICE_DATA_T*) ata_input_data
239   );
240
241   // Look at the first byte to determine the SCSI command to translate.
242   switch (sequence->type)
243   {
244#if !defined(DISABLE_SATI_INQUIRY)
245      case SATI_SEQUENCE_INQUIRY_STANDARD:
246         sati_inquiry_standard_translate_data(
247            sequence, ata_input_data, scsi_io
248         );
249      break;
250
251      case SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER:
252         sati_inquiry_serial_number_translate_data(
253            sequence, ata_input_data, scsi_io
254         );
255      break;
256
257      case SATI_SEQUENCE_INQUIRY_DEVICE_ID:
258         sati_inquiry_device_id_translate_data(
259            sequence, ata_input_data, scsi_io
260         );
261      break;
262
263      case SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE:
264         sati_inquiry_block_device_translate_data(
265            sequence, ata_input_data, scsi_io
266         );
267      break;
268
269      case SATI_SEQUENCE_INQUIRY_ATA_INFORMATION:
270         sati_inquiry_ata_information_translate_data(
271            sequence, ata_input_data, scsi_io
272         );
273      break;
274
275#endif // !defined(DISABLE_SATI_INQUIRY)
276
277#if !defined(DISABLE_SATI_READ_CAPACITY)
278      case SATI_SEQUENCE_READ_CAPACITY_10:
279         sati_read_capacity_10_translate_data(sequence, ata_input_data, scsi_io);
280      break;
281
282      case SATI_SEQUENCE_READ_CAPACITY_16:
283         sati_read_capacity_16_translate_data(sequence, ata_input_data, scsi_io);
284      break;
285#endif // !defined(DISABLE_SATI_READ_CAPACITY)
286
287#if !defined(DISABLE_SATI_MODE_SENSE)
288      case SATI_SEQUENCE_MODE_SENSE_6_CACHING:
289         sati_mode_sense_6_caching_translate_data(
290            sequence, ata_input_data, scsi_io
291         );
292      break;
293
294      case SATI_SEQUENCE_MODE_SENSE_6_INFORMATIONAL_EXCP_CONTROL:
295         sati_mode_sense_6_informational_excp_control_translate_data(
296            sequence, ata_input_data, scsi_io
297         );
298      break;
299
300      case SATI_SEQUENCE_MODE_SENSE_6_READ_WRITE_ERROR:
301         sati_mode_sense_6_read_write_error_translate_data(
302            sequence, ata_input_data, scsi_io
303         );
304      break;
305
306      case SATI_SEQUENCE_MODE_SENSE_6_DISCONNECT_RECONNECT:
307         sati_mode_sense_6_disconnect_reconnect_translate_data(
308            sequence, ata_input_data, scsi_io
309         );
310      break;
311
312      case SATI_SEQUENCE_MODE_SENSE_6_CONTROL:
313         sati_mode_sense_6_control_translate_data(
314            sequence, ata_input_data, scsi_io
315         );
316      break;
317
318      case SATI_SEQUENCE_MODE_SENSE_6_ALL_PAGES:
319         sati_mode_sense_6_all_pages_translate_data(
320            sequence, ata_input_data, scsi_io
321         );
322      break;
323
324      case SATI_SEQUENCE_MODE_SENSE_6_POWER_CONDITION:
325         sati_mode_sense_6_power_condition_translate_data(
326            sequence, ata_input_data, scsi_io
327         );
328      break;
329
330      case SATI_SEQUENCE_MODE_SENSE_10_POWER_CONDITION:
331         sati_mode_sense_10_power_condition_translate_data(
332            sequence, ata_input_data, scsi_io
333         );
334      break;
335
336      case SATI_SEQUENCE_MODE_SENSE_10_CACHING:
337         sati_mode_sense_10_caching_translate_data(
338            sequence, ata_input_data, scsi_io
339         );
340      break;
341
342      case SATI_SEQUENCE_MODE_SENSE_10_INFORMATIONAL_EXCP_CONTROL:
343         sati_mode_sense_10_informational_excp_control_translate_data(
344            sequence, ata_input_data, scsi_io
345         );
346      break;
347
348      case SATI_SEQUENCE_MODE_SENSE_10_READ_WRITE_ERROR:
349         sati_mode_sense_10_read_write_error_translate_data(
350            sequence, ata_input_data, scsi_io
351         );
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