2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
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.
9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
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.
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.
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.
28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
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
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.
55 #include <sys/cdefs.h>
56 __FBSDID("$FreeBSD$");
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.
64 * For situations where compliance is not observed, the SATI will
65 * return an error indication (most likely INVALID FIELD IN CDB sense data).
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>
98 //******************************************************************************
99 //* P R I V A T E M E T H O D S
100 //******************************************************************************
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.
108 * @param[in] error This parameter specifies the contents of the ATA error
109 * register to be translated.
113 void sati_translate_error(
114 SATI_TRANSLATOR_SEQUENCE_T * sequence,
119 if (error & ATA_ERROR_REG_NO_MEDIA_BIT)
121 sati_scsi_sense_data_construct(
124 SCSI_STATUS_CHECK_CONDITION,
125 SCSI_SENSE_NOT_READY,
126 SCSI_ASC_MEDIUM_NOT_PRESENT,
127 SCSI_ASCQ_MEDIUM_NOT_PRESENT
130 else if (error & ATA_ERROR_REG_MEDIA_CHANGE_BIT)
132 sati_scsi_sense_data_construct(
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
141 else if (error & ATA_ERROR_REG_MEDIA_CHANGE_REQUEST_BIT)
143 sati_scsi_sense_data_construct(
146 SCSI_STATUS_CHECK_CONDITION,
147 SCSI_SENSE_UNIT_ATTENTION,
148 SCSI_ASC_MEDIUM_REMOVAL_REQUEST,
149 SCSI_ASCQ_MEDIUM_REMOVAL_REQUEST
152 else if (error & ATA_ERROR_REG_ID_NOT_FOUND_BIT)
154 sati_scsi_sense_data_construct(
157 SCSI_STATUS_CHECK_CONDITION,
158 SCSI_SENSE_ILLEGAL_REQUEST,
159 SCSI_ASC_LBA_OUT_OF_RANGE,
160 SCSI_ASCQ_LBA_OUT_OF_RANGE
163 else if (error & ATA_ERROR_REG_UNCORRECTABLE_BIT)
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(
171 SCSI_STATUS_CHECK_CONDITION,
172 SCSI_SENSE_MEDIUM_ERROR,
173 SCSI_ASC_UNRECOVERED_READ_ERROR,
174 SCSI_ASCQ_UNRECOVERED_READ_ERROR
177 else if ( (sequence->data_direction == SATI_DATA_DIRECTION_OUT)
178 && (error & ATA_ERROR_REG_WRITE_PROTECTED_BIT) )
180 sati_scsi_sense_data_construct(
183 SCSI_STATUS_CHECK_CONDITION,
184 SCSI_SENSE_DATA_PROTECT,
185 SCSI_ASC_WRITE_PROTECTED,
186 SCSI_ASCQ_WRITE_PROTECTED
189 else if (error & ATA_ERROR_REG_ICRC_BIT)
191 sati_scsi_sense_data_construct(
194 SCSI_STATUS_CHECK_CONDITION,
195 SCSI_SENSE_ABORTED_COMMAND,
196 SCSI_ASC_IU_CRC_ERROR_DETECTED,
197 SCSI_ASCQ_IU_CRC_ERROR_DETECTED
200 else // (error & ATA_ERROR_REG_ABORT_BIT)
202 // The ABORT bit has the lowest precedence of all errors.
203 // As a result, it is at the bottom of the conditional
205 sati_scsi_sense_data_construct(
208 SCSI_STATUS_CHECK_CONDITION,
209 SCSI_SENSE_ABORTED_COMMAND,
210 SCSI_ASC_NO_ADDITIONAL_SENSE,
211 SCSI_ASCQ_NO_ADDITIONAL_SENSE
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.
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.
232 void sati_translate_data(
233 SATI_TRANSLATOR_SEQUENCE_T * sequence,
234 void * ata_input_data,
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
243 // Look at the first byte to determine the SCSI command to translate.
244 switch (sequence->type)
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
253 case SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER:
254 sati_inquiry_serial_number_translate_data(
255 sequence, ata_input_data, scsi_io
259 case SATI_SEQUENCE_INQUIRY_DEVICE_ID:
260 sati_inquiry_device_id_translate_data(
261 sequence, ata_input_data, scsi_io
265 case SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE:
266 sati_inquiry_block_device_translate_data(
267 sequence, ata_input_data, scsi_io
271 case SATI_SEQUENCE_INQUIRY_ATA_INFORMATION:
272 sati_inquiry_ata_information_translate_data(
273 sequence, ata_input_data, scsi_io
277 #endif // !defined(DISABLE_SATI_INQUIRY)
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);
284 case SATI_SEQUENCE_READ_CAPACITY_16:
285 sati_read_capacity_16_translate_data(sequence, ata_input_data, scsi_io);
287 #endif // !defined(DISABLE_SATI_READ_CAPACITY)
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
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
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
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
314 case SATI_SEQUENCE_MODE_SENSE_6_CONTROL:
315 sati_mode_sense_6_control_translate_data(
316 sequence, ata_input_data, scsi_io
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
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
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
338 case SATI_SEQUENCE_MODE_SENSE_10_CACHING:
339 sati_mode_sense_10_caching_translate_data(
340 sequence, ata_input_data, scsi_io
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
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
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
362 case SATI_SEQUENCE_MODE_SENSE_10_CONTROL:
363 sati_mode_sense_10_control_translate_data(
364 sequence, ata_input_data, scsi_io
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
373 #endif // !defined(DISABLE_SATI_MODE_SENSE)
380 //******************************************************************************
381 //* P U B L I C M E T H O D S
382 //******************************************************************************
384 SATI_STATUS sati_translate_command(
385 SATI_TRANSLATOR_SEQUENCE_T * sequence,
386 SATI_DEVICE_T * sati_device,
391 SATI_STATUS status = SATI_FAILURE;
392 U8 * cdb = sati_cb_get_cdb_address(scsi_io);
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;
402 * Fail any I/O request with LUN != 0
404 if (sati_cb_get_lun(scsi_io) != 0)
406 sati_scsi_sense_data_construct(
409 SCSI_STATUS_CHECK_CONDITION,
410 SCSI_SENSE_ILLEGAL_REQUEST,
411 SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED,
414 return SATI_FAILURE_CHECK_RESPONSE_DATA;
419 * - the NACA bit in the control byte (last byte) must be 0
421 if ( (sati_get_cdb_byte(cdb, sati_cb_get_cdb_length(scsi_io) - 1)
422 & SCSI_CONTROL_BYTE_NACA_BIT_ENABLE))
424 sati_scsi_sense_data_construct(
427 SCSI_STATUS_CHECK_CONDITION,
428 SCSI_SENSE_ILLEGAL_REQUEST,
429 SCSI_ASC_INVALID_FIELD_IN_CDB,
430 SCSI_ASCQ_INVALID_FIELD_IN_CDB
432 return SATI_FAILURE_CHECK_RESPONSE_DATA;
436 * Per SAT "Error and sense reporting" section. All subsequent IOs after
437 * a device fault should receive INTERNAL TARGET FAILURE sense data.
439 if (sati_device->state == SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED)
441 sati_scsi_sense_data_construct(
444 SCSI_STATUS_CHECK_CONDITION,
445 SCSI_SENSE_HARDWARE_ERROR,
446 SCSI_ASC_INTERNAL_TARGET_FAILURE,
447 SCSI_ASCQ_INTERNAL_TARGET_FAILURE
449 return SATI_FAILURE_CHECK_RESPONSE_DATA;
452 if(sequence->state == SATI_SEQUENCE_STATE_INITIAL)
454 sequence->command_specific_data.scratch = 0;
455 sequence->number_data_bytes_set = 0;
459 #ifdef SATI_TRANSPORT_SUPPORTS_SATA
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);
465 #endif // SATI_TRANSPORT_SUPPORTS_SATA
467 // Look at the first byte to determine the SCSI command to translate.
468 switch (sati_get_cdb_byte(cdb, 0))
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
476 #endif // !defined(DISABLE_SATI_REPORT_LUNS)
478 #if !defined(DISABLE_SATI_INQUIRY)
480 status = sati_inquiry_translate_command(
481 sequence, scsi_io, ata_io
484 #endif // !defined(DISABLE_SATI_INQUIRY)
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
493 case SCSI_MODE_SENSE_10:
494 status = sati_mode_sense_10_translate_command(
495 sequence, scsi_io, ata_io
498 #endif // !defined(DISABLE_SATI_MODE_SENSE)
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
507 case SCSI_MODE_SELECT_10:
508 status = sati_mode_select_10_translate_command(
509 sequence, scsi_io, ata_io
512 #endif // !defined(DISABLE_SATI_MODE_SELECT)
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
520 #endif // !defined(DISABLE_SATI_TEST_UNIT_READY)
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
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
536 status = SATI_FAILURE_CHECK_RESPONSE_DATA;
538 #endif // !defined(DISABLE_SATI_READ_CAPACITY)
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
546 #endif // !defined(DISABLE_SATI_REQUEST_SENSE)
549 status = sati_read_6_translate_command(sequence, scsi_io, ata_io);
553 status = sati_read_10_translate_command(sequence, scsi_io, ata_io);
557 status = sati_read_12_translate_command(sequence, scsi_io, ata_io);
561 status = sati_read_16_translate_command(sequence, scsi_io, ata_io);
565 status = sati_write_6_translate_command(sequence, scsi_io, ata_io);
569 status = sati_write_10_translate_command(sequence, scsi_io, ata_io);
573 status = sati_write_12_translate_command(sequence, scsi_io, ata_io);
577 status = sati_write_16_translate_command(sequence, scsi_io, ata_io);
580 #if !defined(DISABLE_SATI_VERIFY)
582 status = sati_verify_10_translate_command(sequence, scsi_io, ata_io);
586 status = sati_verify_12_translate_command(sequence, scsi_io, ata_io);
590 status = sati_verify_16_translate_command(sequence, scsi_io, ata_io);
592 #endif // !defined(DISABLE_SATI_VERIFY)
594 #if !defined(DISABLE_SATI_WRITE_AND_VERIFY) \
595 && !defined(DISABLE_SATI_VERIFY) \
596 && !defined(DISABLE_SATI_WRITE)
598 case SCSI_WRITE_AND_VERIFY_10:
599 status = sati_write_and_verify_10_translate_command(sequence, scsi_io, ata_io);
602 case SCSI_WRITE_AND_VERIFY_12:
603 status = sati_write_and_verify_12_translate_command(sequence, scsi_io, ata_io);
606 case SCSI_WRITE_AND_VERIFY_16:
607 status = sati_write_and_verify_16_translate_command(sequence, scsi_io, ata_io);
609 #endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY)
610 // && !defined(DISABLE_SATI_VERIFY)
611 // && !defined(DISABLE_SATI_WRITE)
613 #if !defined(DISABLE_SATI_REASSIGN_BLOCKS)
614 case SCSI_REASSIGN_BLOCKS:
615 status = sati_reassign_blocks_translate_command(sequence, scsi_io, ata_io);
617 #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
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);
624 #endif // !defined(DISABLE_SATI_SYNCHRONIZE_CACHE)
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
632 #endif // !defined(DISABLE_SATI_START_STOP_UNIT)
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);
639 #endif // !defined(DISABLE_SATI_WRITE_LONG)
641 #if !defined(DISABLE_SATI_LOG_SENSE)
643 status = sati_log_sense_translate_command(sequence, scsi_io, ata_io);
645 #endif // !defined(DISABLE_SATI_LOG_SENSE)
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(
653 SCSI_STATUS_CHECK_CONDITION,
654 SCSI_SENSE_ILLEGAL_REQUEST,
655 SCSI_ASC_INVALID_COMMAND_OPERATION_CODE,
656 SCSI_ASCQ_INVALID_COMMAND_OPERATION_CODE
658 //returning status now to keep sense data set above
659 return SATI_FAILURE_CHECK_RESPONSE_DATA;
662 #if !defined(DISABLE_SATI_UNMAP)
664 status = sati_unmap_translate_command(sequence, scsi_io, ata_io);
666 #endif // !defined(DISABLE_SATI_UNMAP)
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);
673 case SCSI_ATA_PASSTHRU_16:
674 status = sati_passthrough_16_translate_command(sequence, scsi_io, ata_io);
677 #endif // !define(DISABLE_SATI_ATA_PASSTHRU)
679 #if !defined(DISABLE_SATI_READ_BUFFER)
680 case SCSI_READ_BUFFER:
681 status = sati_read_buffer_translate_command(sequence, scsi_io, ata_io);
683 #endif //!defined(DISABLE_SATI_READ_BUFFER)
685 #if !defined(DISABLE_SATI_WRITE_BUFFER)
686 case SCSI_WRITE_BUFFER:
687 status = sati_write_buffer_translate_command(sequence, scsi_io, ata_io);
689 #endif //!defined(DISABLE_SATI_WRITE_BUFFER)
691 status = SATI_FAILURE_CHECK_RESPONSE_DATA;
695 if( (status == SATI_FAILURE_CHECK_RESPONSE_DATA) &&
696 !(sequence->is_sense_response_set) )
698 sati_scsi_sense_data_construct(
701 SCSI_STATUS_CHECK_CONDITION,
702 SCSI_SENSE_ILLEGAL_REQUEST,
703 SCSI_ASC_INVALID_FIELD_IN_CDB,
704 SCSI_ASCQ_INVALID_FIELD_IN_CDB
710 // -----------------------------------------------------------------------------
712 #if !defined(DISABLE_SATI_TASK_MANAGEMENT)
713 SATI_STATUS sati_translate_task_management(
714 SATI_TRANSLATOR_SEQUENCE_T * sequence,
715 SATI_DEVICE_T * sati_device,
720 SATI_STATUS status=SATI_FAILURE;
721 U8 task_function = sati_cb_get_task_function(scsi_task);
723 sequence->device = sati_device;
725 switch (task_function)
728 * @todo We need to update the ABORT_TASK and ABORT_TASK_SET to be
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);
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);
740 status = SATI_FAILURE;
744 status = SATI_FAILURE;
750 #endif // !defined(DISABLE_SATI_TASK_MANAGEMENT)
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)
765 SATI_STATUS sati_check_data_io(
766 SATI_TRANSLATOR_SEQUENCE_T * sequence
769 if(sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE)
771 return SATI_SEQUENCE_INCOMPLETE;
773 else if(sequence->number_data_bytes_set < sequence->allocation_length)
775 return SATI_COMPLETE_IO_DONE_EARLY;
779 return SATI_COMPLETE;
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 // -----------------------------------------------------------------------------
793 SATI_STATUS sati_translate_command_response(
794 SATI_TRANSLATOR_SEQUENCE_T * sequence,
799 SATI_STATUS status = SATI_COMPLETE;
800 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
804 * If the device fault bit is set in the status register, then
805 * set the sense data and return.
807 ata_status = (U8) sati_get_ata_status(register_fis);
808 if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT)
810 sati_scsi_sense_data_construct(
813 SCSI_STATUS_CHECK_CONDITION,
814 SCSI_SENSE_HARDWARE_ERROR,
815 SCSI_ASC_INTERNAL_TARGET_FAILURE,
816 SCSI_ASCQ_INTERNAL_TARGET_FAILURE
819 sequence->device->state = SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED;
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,
827 return SATI_FAILURE_CHECK_RESPONSE_DATA;
830 // Look at the sequence type to determine the response translation method
832 switch (sequence->type)
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
840 #endif // !defined(DISABLE_SATI_TEST_UNIT_READY)
842 #if !defined(DISABLE_SATI_INQUIRY) \
843 || !defined(DISABLE_SATI_READY_CAPACITY) \
844 || !defined(DISABLE_SATI_MODE_SENSE)
846 case SATI_SEQUENCE_INQUIRY_EXECUTE_DEVICE_DIAG:
848 if (ata_status & ATA_STATUS_REG_ERROR_BIT)
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);
856 sati_inquiry_ata_information_finish_translation(
861 status = sati_check_data_io(sequence);
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)
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);
896 void * ata_data = sati_cb_get_ata_data_address(ata_io);
900 status = SATI_FAILURE;
904 sati_translate_data(sequence, ata_data, scsi_io);
905 status = sati_check_data_io(sequence);
909 #endif // !defined(DISABLE_SATI_INQUIRY)
910 // && !defined(DISABLE_SATI_READY_CAPACITY)
911 // && !defined(DISABLE_SATI_MODE_SENSE)
913 #if !defined(DISABLE_SATI_MODE_SELECT)
914 case SATI_SEQUENCE_MODE_SELECT_MODE_PAGE_CACHING:
916 status = sati_mode_select_translate_response(
917 sequence, scsi_io, ata_io
919 if(status == SATI_COMPLETE)
921 status = sati_check_data_io(sequence);
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)
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);
936 status = sati_check_data_io(sequence);
939 #endif // !defined(DISABLE_SATI_MODE_SELECT)
941 #if !defined(DISABLE_SATI_WRITE_AND_VERIFY)
942 case SATI_SEQUENCE_WRITE_AND_VERIFY:
944 if (ata_status & ATA_STATUS_REG_ERROR_BIT)
946 U8 error = (U8) sati_get_ata_error(register_fis);
947 sati_translate_error(sequence, scsi_io, error);
949 return SATI_FAILURE_CHECK_RESPONSE_DATA;
953 status = sati_write_and_verify_translate_response(
960 #endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY)
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)
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);
980 if(sequence->state == SATI_SEQUENCE_STATE_READ_ERROR )
982 sati_scsi_read_error_sense_construct(
986 SCSI_STATUS_CHECK_CONDITION,
987 SCSI_SENSE_MEDIUM_ERROR,
988 SCSI_ASC_UNRECOVERED_READ_ERROR,
989 SCSI_ASCQ_UNRECOVERED_READ_ERROR
991 sequence->state = SATI_SEQUENCE_STATE_FINAL;
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)
1001 /** @todo update the contents of the CDB directly? Should be
1002 * done during previous command translation?
1004 status = SATI_SEQUENCE_INCOMPLETE;
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
1015 if(status == SATI_COMPLETE)
1017 status = sati_check_data_io(sequence);
1020 #endif //!defined(DISABLE_SATI_READ_BUFFER)
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
1029 #endif //!defined(DISABLE_SATI_WRITE_BUFFER)
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
1036 if(status == SATI_COMPLETE)
1038 status = sati_check_data_io(sequence);
1041 #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
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
1048 if(status == SATI_COMPLETE)
1050 status = sati_check_data_io(sequence);
1053 #endif // !defined(DISABLE_SATI_START_STOP_UNIT)
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
1061 if(status == SATI_COMPLETE)
1063 status = sati_check_data_io(sequence);
1066 #endif // !defined(DISABLE_SATI_REQUEST_SENSE)
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
1073 if(status == SATI_COMPLETE)
1075 status = sati_check_data_io(sequence);
1078 #endif // !defined(DISABLE_SATI_WRITE_LONG)
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
1088 if(status == SATI_COMPLETE)
1090 status = sati_check_data_io(sequence);
1093 #endif // !defined(DISABLE_SATI_LOG_SENSE)
1095 #if !defined(DISABLE_SATI_UNMAP)
1096 case SATI_SEQUENCE_UNMAP:
1097 status = sati_unmap_translate_response(
1098 sequence, scsi_io, ata_io
1101 #endif // !defined(DISABLE_SATI_UNMAP)
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
1110 #endif // !defined(DISABLE_SATI_ATA_PASSTHROUGH)
1113 status = SATI_FAILURE_INVALID_SEQUENCE_TYPE;
1120 // -----------------------------------------------------------------------------
1122 #if !defined(DISABLE_SATI_TASK_MANAGEMENT)
1123 SATI_STATUS sati_translate_task_response(
1124 SATI_TRANSLATOR_SEQUENCE_T * sequence,
1129 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
1130 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
1134 * If the device fault bit is set in the status register, then
1135 * set the sense data and return.
1137 ata_status = (U8) sati_get_ata_status(register_fis);
1138 if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT)
1140 sati_scsi_response_data_construct(
1143 SCSI_TASK_MGMT_FUNC_FAILED
1145 return SATI_FAILURE_CHECK_RESPONSE_DATA;
1148 // Look at the sequence type to determine the response translation method
1150 switch (sequence->type)
1152 case SATI_SEQUENCE_LUN_RESET:
1153 if (ata_status & ATA_STATUS_REG_ERROR_BIT)
1155 sati_scsi_response_data_construct(
1156 sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED);
1160 sati_scsi_response_data_construct(
1161 sequence, scsi_io, SCSI_TASK_MGMT_FUNC_COMPLETE);
1164 status = SATI_COMPLETE;
1167 #if !defined(DISABLE_SATI_ABORT_TASK_SET)
1168 case SATI_SEQUENCE_ABORT_TASK_SET:
1169 if (ata_status & ATA_STATUS_REG_ERROR_BIT)
1171 sati_scsi_response_data_construct(
1172 sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED);
1176 void * ata_data = sati_cb_get_ata_data_address(ata_io);
1178 if(ata_data == NULL)
1180 status = SATI_FAILURE;
1184 status = sati_abort_task_set_translate_data(
1192 #endif // !defined(DISABLE_SATI_ABORT_TASK_SET)
1195 status = SATI_FAILURE_INVALID_SEQUENCE_TYPE;
1201 #endif // !defined(DISABLE_SATI_TASK_MANAGEMENT)
1203 #if !defined(ENABLE_MINIMUM_MEMORY_MODE)
1204 U32 sati_get_sat_compliance_version(
1208 return 2; // Compliant with SAT-2.
1211 U32 sati_get_sat_compliance_version_revision(
1215 return 7; // Compliant with SAT-2 revision 7.
1218 #endif // !defined(ENABLE_MINIMUM_MEMORY_MODE)
1220 U16 sati_get_number_data_bytes_set(
1221 SATI_TRANSLATOR_SEQUENCE_T * sequence
1224 return sequence->number_data_bytes_set;
1227 void sati_sequence_construct(
1228 SATI_TRANSLATOR_SEQUENCE_T * sequence
1231 sequence->state = SATI_SEQUENCE_STATE_INITIAL;
1234 void sati_sequence_terminate(
1235 SATI_TRANSLATOR_SEQUENCE_T * sequence,
1240 // Decode the sequence type to determine how to handle the termination
1241 // of the translation method.
1242 switch (sequence->type)
1244 case SATI_SEQUENCE_UNMAP:
1245 sati_unmap_terminate(sequence,scsi_io,ata_io);