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.
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
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.
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.
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.
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
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
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.
53 #include <sys/cdefs.h>
54 __FBSDID("$FreeBSD$");
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.
62 * For situations where compliance is not observed, the SATI will
63 * return an error indication (most likely INVALID FIELD IN CDB sense data).
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>
96 //******************************************************************************
97 //* P R I V A T E M E T H O D S
98 //******************************************************************************
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.
106 * @param[in] error This parameter specifies the contents of the ATA error
107 * register to be translated.
111 void sati_translate_error(
112 SATI_TRANSLATOR_SEQUENCE_T * sequence,
117 if (error & ATA_ERROR_REG_NO_MEDIA_BIT)
119 sati_scsi_sense_data_construct(
122 SCSI_STATUS_CHECK_CONDITION,
123 SCSI_SENSE_NOT_READY,
124 SCSI_ASC_MEDIUM_NOT_PRESENT,
125 SCSI_ASCQ_MEDIUM_NOT_PRESENT
128 else if (error & ATA_ERROR_REG_MEDIA_CHANGE_BIT)
130 sati_scsi_sense_data_construct(
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
139 else if (error & ATA_ERROR_REG_MEDIA_CHANGE_REQUEST_BIT)
141 sati_scsi_sense_data_construct(
144 SCSI_STATUS_CHECK_CONDITION,
145 SCSI_SENSE_UNIT_ATTENTION,
146 SCSI_ASC_MEDIUM_REMOVAL_REQUEST,
147 SCSI_ASCQ_MEDIUM_REMOVAL_REQUEST
150 else if (error & ATA_ERROR_REG_ID_NOT_FOUND_BIT)
152 sati_scsi_sense_data_construct(
155 SCSI_STATUS_CHECK_CONDITION,
156 SCSI_SENSE_ILLEGAL_REQUEST,
157 SCSI_ASC_LBA_OUT_OF_RANGE,
158 SCSI_ASCQ_LBA_OUT_OF_RANGE
161 else if (error & ATA_ERROR_REG_UNCORRECTABLE_BIT)
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(
169 SCSI_STATUS_CHECK_CONDITION,
170 SCSI_SENSE_MEDIUM_ERROR,
171 SCSI_ASC_UNRECOVERED_READ_ERROR,
172 SCSI_ASCQ_UNRECOVERED_READ_ERROR
175 else if ( (sequence->data_direction == SATI_DATA_DIRECTION_OUT)
176 && (error & ATA_ERROR_REG_WRITE_PROTECTED_BIT) )
178 sati_scsi_sense_data_construct(
181 SCSI_STATUS_CHECK_CONDITION,
182 SCSI_SENSE_DATA_PROTECT,
183 SCSI_ASC_WRITE_PROTECTED,
184 SCSI_ASCQ_WRITE_PROTECTED
187 else if (error & ATA_ERROR_REG_ICRC_BIT)
189 sati_scsi_sense_data_construct(
192 SCSI_STATUS_CHECK_CONDITION,
193 SCSI_SENSE_ABORTED_COMMAND,
194 SCSI_ASC_IU_CRC_ERROR_DETECTED,
195 SCSI_ASCQ_IU_CRC_ERROR_DETECTED
198 else // (error & ATA_ERROR_REG_ABORT_BIT)
200 // The ABORT bit has the lowest precedence of all errors.
201 // As a result, it is at the bottom of the conditional
203 sati_scsi_sense_data_construct(
206 SCSI_STATUS_CHECK_CONDITION,
207 SCSI_SENSE_ABORTED_COMMAND,
208 SCSI_ASC_NO_ADDITIONAL_SENSE,
209 SCSI_ASCQ_NO_ADDITIONAL_SENSE
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.
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.
230 void sati_translate_data(
231 SATI_TRANSLATOR_SEQUENCE_T * sequence,
232 void * ata_input_data,
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
241 // Look at the first byte to determine the SCSI command to translate.
242 switch (sequence->type)
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
251 case SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER:
252 sati_inquiry_serial_number_translate_data(
253 sequence, ata_input_data, scsi_io
257 case SATI_SEQUENCE_INQUIRY_DEVICE_ID:
258 sati_inquiry_device_id_translate_data(
259 sequence, ata_input_data, scsi_io
263 case SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE:
264 sati_inquiry_block_device_translate_data(
265 sequence, ata_input_data, scsi_io
269 case SATI_SEQUENCE_INQUIRY_ATA_INFORMATION:
270 sati_inquiry_ata_information_translate_data(
271 sequence, ata_input_data, scsi_io
275 #endif // !defined(DISABLE_SATI_INQUIRY)
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);
282 case SATI_SEQUENCE_READ_CAPACITY_16:
283 sati_read_capacity_16_translate_data(sequence, ata_input_data, scsi_io);
285 #endif // !defined(DISABLE_SATI_READ_CAPACITY)
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
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
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
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
312 case SATI_SEQUENCE_MODE_SENSE_6_CONTROL:
313 sati_mode_sense_6_control_translate_data(
314 sequence, ata_input_data, scsi_io
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
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
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
336 case SATI_SEQUENCE_MODE_SENSE_10_CACHING:
337 sati_mode_sense_10_caching_translate_data(
338 sequence, ata_input_data, scsi_io
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
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
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
360 case SATI_SEQUENCE_MODE_SENSE_10_CONTROL:
361 sati_mode_sense_10_control_translate_data(
362 sequence, ata_input_data, scsi_io
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
371 #endif // !defined(DISABLE_SATI_MODE_SENSE)
378 //******************************************************************************
379 //* P U B L I C M E T H O D S
380 //******************************************************************************
382 SATI_STATUS sati_translate_command(
383 SATI_TRANSLATOR_SEQUENCE_T * sequence,
384 SATI_DEVICE_T * sati_device,
389 SATI_STATUS status = SATI_FAILURE;
390 U8 * cdb = sati_cb_get_cdb_address(scsi_io);
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;
400 * Fail any I/O request with LUN != 0
402 if (sati_cb_get_lun(scsi_io) != 0)
404 sati_scsi_sense_data_construct(
407 SCSI_STATUS_CHECK_CONDITION,
408 SCSI_SENSE_ILLEGAL_REQUEST,
409 SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED,
412 return SATI_FAILURE_CHECK_RESPONSE_DATA;
417 * - the NACA bit in the control byte (last byte) must be 0
419 if ( (sati_get_cdb_byte(cdb, sati_cb_get_cdb_length(scsi_io) - 1)
420 & SCSI_CONTROL_BYTE_NACA_BIT_ENABLE))
422 sati_scsi_sense_data_construct(
425 SCSI_STATUS_CHECK_CONDITION,
426 SCSI_SENSE_ILLEGAL_REQUEST,
427 SCSI_ASC_INVALID_FIELD_IN_CDB,
428 SCSI_ASCQ_INVALID_FIELD_IN_CDB
430 return SATI_FAILURE_CHECK_RESPONSE_DATA;
434 * Per SAT "Error and sense reporting" section. All subsequent IOs after
435 * a device fault should receive INTERNAL TARGET FAILURE sense data.
437 if (sati_device->state == SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED)
439 sati_scsi_sense_data_construct(
442 SCSI_STATUS_CHECK_CONDITION,
443 SCSI_SENSE_HARDWARE_ERROR,
444 SCSI_ASC_INTERNAL_TARGET_FAILURE,
445 SCSI_ASCQ_INTERNAL_TARGET_FAILURE
447 return SATI_FAILURE_CHECK_RESPONSE_DATA;
450 if(sequence->state == SATI_SEQUENCE_STATE_INITIAL)
452 sequence->command_specific_data.scratch = 0;
453 sequence->number_data_bytes_set = 0;
457 #ifdef SATI_TRANSPORT_SUPPORTS_SATA
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);
463 #endif // SATI_TRANSPORT_SUPPORTS_SATA
465 // Look at the first byte to determine the SCSI command to translate.
466 switch (sati_get_cdb_byte(cdb, 0))
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
474 #endif // !defined(DISABLE_SATI_REPORT_LUNS)
476 #if !defined(DISABLE_SATI_INQUIRY)
478 status = sati_inquiry_translate_command(
479 sequence, scsi_io, ata_io
482 #endif // !defined(DISABLE_SATI_INQUIRY)
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
491 case SCSI_MODE_SENSE_10:
492 status = sati_mode_sense_10_translate_command(
493 sequence, scsi_io, ata_io
496 #endif // !defined(DISABLE_SATI_MODE_SENSE)
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
505 case SCSI_MODE_SELECT_10:
506 status = sati_mode_select_10_translate_command(
507 sequence, scsi_io, ata_io
510 #endif // !defined(DISABLE_SATI_MODE_SELECT)
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
518 #endif // !defined(DISABLE_SATI_TEST_UNIT_READY)
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
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
534 status = SATI_FAILURE_CHECK_RESPONSE_DATA;
536 #endif // !defined(DISABLE_SATI_READ_CAPACITY)
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
544 #endif // !defined(DISABLE_SATI_REQUEST_SENSE)
547 status = sati_read_6_translate_command(sequence, scsi_io, ata_io);
551 status = sati_read_10_translate_command(sequence, scsi_io, ata_io);
555 status = sati_read_12_translate_command(sequence, scsi_io, ata_io);
559 status = sati_read_16_translate_command(sequence, scsi_io, ata_io);
563 status = sati_write_6_translate_command(sequence, scsi_io, ata_io);
567 status = sati_write_10_translate_command(sequence, scsi_io, ata_io);
571 status = sati_write_12_translate_command(sequence, scsi_io, ata_io);
575 status = sati_write_16_translate_command(sequence, scsi_io, ata_io);
578 #if !defined(DISABLE_SATI_VERIFY)
580 status = sati_verify_10_translate_command(sequence, scsi_io, ata_io);
584 status = sati_verify_12_translate_command(sequence, scsi_io, ata_io);
588 status = sati_verify_16_translate_command(sequence, scsi_io, ata_io);
590 #endif // !defined(DISABLE_SATI_VERIFY)
592 #if !defined(DISABLE_SATI_WRITE_AND_VERIFY) \
593 && !defined(DISABLE_SATI_VERIFY) \
594 && !defined(DISABLE_SATI_WRITE)
596 case SCSI_WRITE_AND_VERIFY_10:
597 status = sati_write_and_verify_10_translate_command(sequence, scsi_io, ata_io);
600 case SCSI_WRITE_AND_VERIFY_12:
601 status = sati_write_and_verify_12_translate_command(sequence, scsi_io, ata_io);
604 case SCSI_WRITE_AND_VERIFY_16:
605 status = sati_write_and_verify_16_translate_command(sequence, scsi_io, ata_io);
607 #endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY)
608 // && !defined(DISABLE_SATI_VERIFY)
609 // && !defined(DISABLE_SATI_WRITE)
611 #if !defined(DISABLE_SATI_REASSIGN_BLOCKS)
612 case SCSI_REASSIGN_BLOCKS:
613 status = sati_reassign_blocks_translate_command(sequence, scsi_io, ata_io);
615 #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
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);
622 #endif // !defined(DISABLE_SATI_SYNCHRONIZE_CACHE)
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
630 #endif // !defined(DISABLE_SATI_START_STOP_UNIT)
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);
637 #endif // !defined(DISABLE_SATI_WRITE_LONG)
639 #if !defined(DISABLE_SATI_LOG_SENSE)
641 status = sati_log_sense_translate_command(sequence, scsi_io, ata_io);
643 #endif // !defined(DISABLE_SATI_LOG_SENSE)
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(
651 SCSI_STATUS_CHECK_CONDITION,
652 SCSI_SENSE_ILLEGAL_REQUEST,
653 SCSI_ASC_INVALID_COMMAND_OPERATION_CODE,
654 SCSI_ASCQ_INVALID_COMMAND_OPERATION_CODE
656 //returning status now to keep sense data set above
657 return SATI_FAILURE_CHECK_RESPONSE_DATA;
660 #if !defined(DISABLE_SATI_UNMAP)
662 status = sati_unmap_translate_command(sequence, scsi_io, ata_io);
664 #endif // !defined(DISABLE_SATI_UNMAP)
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);
671 case SCSI_ATA_PASSTHRU_16:
672 status = sati_passthrough_16_translate_command(sequence, scsi_io, ata_io);
675 #endif // !define(DISABLE_SATI_ATA_PASSTHRU)
677 #if !defined(DISABLE_SATI_READ_BUFFER)
678 case SCSI_READ_BUFFER:
679 status = sati_read_buffer_translate_command(sequence, scsi_io, ata_io);
681 #endif //!defined(DISABLE_SATI_READ_BUFFER)
683 #if !defined(DISABLE_SATI_WRITE_BUFFER)
684 case SCSI_WRITE_BUFFER:
685 status = sati_write_buffer_translate_command(sequence, scsi_io, ata_io);
687 #endif //!defined(DISABLE_SATI_WRITE_BUFFER)
689 status = SATI_FAILURE_CHECK_RESPONSE_DATA;
693 if( (status == SATI_FAILURE_CHECK_RESPONSE_DATA) &&
694 !(sequence->is_sense_response_set) )
696 sati_scsi_sense_data_construct(
699 SCSI_STATUS_CHECK_CONDITION,
700 SCSI_SENSE_ILLEGAL_REQUEST,
701 SCSI_ASC_INVALID_FIELD_IN_CDB,
702 SCSI_ASCQ_INVALID_FIELD_IN_CDB
708 // -----------------------------------------------------------------------------
710 #if !defined(DISABLE_SATI_TASK_MANAGEMENT)
711 SATI_STATUS sati_translate_task_management(
712 SATI_TRANSLATOR_SEQUENCE_T * sequence,
713 SATI_DEVICE_T * sati_device,
718 SATI_STATUS status=SATI_FAILURE;
719 U8 task_function = sati_cb_get_task_function(scsi_task);
721 sequence->device = sati_device;
723 switch (task_function)
726 * @todo We need to update the ABORT_TASK and ABORT_TASK_SET to be
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);
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);
738 status = SATI_FAILURE;
742 status = SATI_FAILURE;
748 #endif // !defined(DISABLE_SATI_TASK_MANAGEMENT)
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)
763 SATI_STATUS sati_check_data_io(
764 SATI_TRANSLATOR_SEQUENCE_T * sequence
767 if(sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE)
769 return SATI_SEQUENCE_INCOMPLETE;
771 else if(sequence->number_data_bytes_set < sequence->allocation_length)
773 return SATI_COMPLETE_IO_DONE_EARLY;
777 return SATI_COMPLETE;
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 // -----------------------------------------------------------------------------
791 SATI_STATUS sati_translate_command_response(
792 SATI_TRANSLATOR_SEQUENCE_T * sequence,
797 SATI_STATUS status = SATI_COMPLETE;
798 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
802 * If the device fault bit is set in the status register, then
803 * set the sense data and return.
805 ata_status = (U8) sati_get_ata_status(register_fis);
806 if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT)
808 sati_scsi_sense_data_construct(
811 SCSI_STATUS_CHECK_CONDITION,
812 SCSI_SENSE_HARDWARE_ERROR,
813 SCSI_ASC_INTERNAL_TARGET_FAILURE,
814 SCSI_ASCQ_INTERNAL_TARGET_FAILURE
817 sequence->device->state = SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED;
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,
825 return SATI_FAILURE_CHECK_RESPONSE_DATA;
828 // Look at the sequence type to determine the response translation method
830 switch (sequence->type)
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
838 #endif // !defined(DISABLE_SATI_TEST_UNIT_READY)
840 #if !defined(DISABLE_SATI_INQUIRY) \
841 || !defined(DISABLE_SATI_READY_CAPACITY) \
842 || !defined(DISABLE_SATI_MODE_SENSE)
844 case SATI_SEQUENCE_INQUIRY_EXECUTE_DEVICE_DIAG:
846 if (ata_status & ATA_STATUS_REG_ERROR_BIT)
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);
854 sati_inquiry_ata_information_finish_translation(
859 status = sati_check_data_io(sequence);
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)
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);
894 void * ata_data = sati_cb_get_ata_data_address(ata_io);
898 status = SATI_FAILURE;
902 sati_translate_data(sequence, ata_data, scsi_io);
903 status = sati_check_data_io(sequence);
907 #endif // !defined(DISABLE_SATI_INQUIRY)
908 // && !defined(DISABLE_SATI_READY_CAPACITY)
909 // && !defined(DISABLE_SATI_MODE_SENSE)
911 #if !defined(DISABLE_SATI_MODE_SELECT)
912 case SATI_SEQUENCE_MODE_SELECT_MODE_PAGE_CACHING:
914 status = sati_mode_select_translate_response(
915 sequence, scsi_io, ata_io
917 if(status == SATI_COMPLETE)
919 status = sati_check_data_io(sequence);
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)
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);
934 status = sati_check_data_io(sequence);
937 #endif // !defined(DISABLE_SATI_MODE_SELECT)
939 #if !defined(DISABLE_SATI_WRITE_AND_VERIFY)
940 case SATI_SEQUENCE_WRITE_AND_VERIFY:
942 if (ata_status & ATA_STATUS_REG_ERROR_BIT)
944 U8 error = (U8) sati_get_ata_error(register_fis);
945 sati_translate_error(sequence, scsi_io, error);
947 return SATI_FAILURE_CHECK_RESPONSE_DATA;
951 status = sati_write_and_verify_translate_response(
958 #endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY)
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)
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);
978 if(sequence->state == SATI_SEQUENCE_STATE_READ_ERROR )
980 sati_scsi_read_error_sense_construct(
984 SCSI_STATUS_CHECK_CONDITION,
985 SCSI_SENSE_MEDIUM_ERROR,
986 SCSI_ASC_UNRECOVERED_READ_ERROR,
987 SCSI_ASCQ_UNRECOVERED_READ_ERROR
989 sequence->state = SATI_SEQUENCE_STATE_FINAL;
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)
999 /** @todo update the contents of the CDB directly? Should be
1000 * done during previous command translation?
1002 status = SATI_SEQUENCE_INCOMPLETE;
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
1013 if(status == SATI_COMPLETE)
1015 status = sati_check_data_io(sequence);
1018 #endif //!defined(DISABLE_SATI_READ_BUFFER)
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
1027 #endif //!defined(DISABLE_SATI_WRITE_BUFFER)
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
1034 if(status == SATI_COMPLETE)
1036 status = sati_check_data_io(sequence);
1039 #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
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
1046 if(status == SATI_COMPLETE)
1048 status = sati_check_data_io(sequence);
1051 #endif // !defined(DISABLE_SATI_START_STOP_UNIT)
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
1059 if(status == SATI_COMPLETE)
1061 status = sati_check_data_io(sequence);
1064 #endif // !defined(DISABLE_SATI_REQUEST_SENSE)
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
1071 if(status == SATI_COMPLETE)
1073 status = sati_check_data_io(sequence);
1076 #endif // !defined(DISABLE_SATI_WRITE_LONG)
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
1086 if(status == SATI_COMPLETE)
1088 status = sati_check_data_io(sequence);
1091 #endif // !defined(DISABLE_SATI_LOG_SENSE)
1093 #if !defined(DISABLE_SATI_UNMAP)
1094 case SATI_SEQUENCE_UNMAP:
1095 status = sati_unmap_translate_response(
1096 sequence, scsi_io, ata_io
1099 #endif // !defined(DISABLE_SATI_UNMAP)
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
1108 #endif // !defined(DISABLE_SATI_ATA_PASSTHROUGH)
1111 status = SATI_FAILURE_INVALID_SEQUENCE_TYPE;
1118 // -----------------------------------------------------------------------------
1120 #if !defined(DISABLE_SATI_TASK_MANAGEMENT)
1121 SATI_STATUS sati_translate_task_response(
1122 SATI_TRANSLATOR_SEQUENCE_T * sequence,
1127 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
1128 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
1132 * If the device fault bit is set in the status register, then
1133 * set the sense data and return.
1135 ata_status = (U8) sati_get_ata_status(register_fis);
1136 if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT)
1138 sati_scsi_response_data_construct(
1141 SCSI_TASK_MGMT_FUNC_FAILED
1143 return SATI_FAILURE_CHECK_RESPONSE_DATA;
1146 // Look at the sequence type to determine the response translation method
1148 switch (sequence->type)
1150 case SATI_SEQUENCE_LUN_RESET:
1151 if (ata_status & ATA_STATUS_REG_ERROR_BIT)
1153 sati_scsi_response_data_construct(
1154 sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED);
1158 sati_scsi_response_data_construct(
1159 sequence, scsi_io, SCSI_TASK_MGMT_FUNC_COMPLETE);
1162 status = SATI_COMPLETE;
1165 #if !defined(DISABLE_SATI_ABORT_TASK_SET)
1166 case SATI_SEQUENCE_ABORT_TASK_SET:
1167 if (ata_status & ATA_STATUS_REG_ERROR_BIT)
1169 sati_scsi_response_data_construct(
1170 sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED);
1174 void * ata_data = sati_cb_get_ata_data_address(ata_io);
1176 if(ata_data == NULL)
1178 status = SATI_FAILURE;
1182 status = sati_abort_task_set_translate_data(
1190 #endif // !defined(DISABLE_SATI_ABORT_TASK_SET)
1193 status = SATI_FAILURE_INVALID_SEQUENCE_TYPE;
1199 #endif // !defined(DISABLE_SATI_TASK_MANAGEMENT)
1201 #if !defined(ENABLE_MINIMUM_MEMORY_MODE)
1202 U32 sati_get_sat_compliance_version(
1206 return 2; // Compliant with SAT-2.
1209 U32 sati_get_sat_compliance_version_revision(
1213 return 7; // Compliant with SAT-2 revision 7.
1216 #endif // !defined(ENABLE_MINIMUM_MEMORY_MODE)
1218 U16 sati_get_number_data_bytes_set(
1219 SATI_TRANSLATOR_SEQUENCE_T * sequence
1222 return sequence->number_data_bytes_set;
1225 void sati_sequence_construct(
1226 SATI_TRANSLATOR_SEQUENCE_T * sequence
1229 sequence->state = SATI_SEQUENCE_STATE_INITIAL;
1232 void sati_sequence_terminate(
1233 SATI_TRANSLATOR_SEQUENCE_T * sequence,
1238 // Decode the sequence type to determine how to handle the termination
1239 // of the translation method.
1240 switch (sequence->type)
1242 case SATI_SEQUENCE_UNMAP:
1243 sati_unmap_terminate(sequence,scsi_io,ata_io);