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$");
61 * @brief This file contains the method implementations required to
62 * translate the SCSI inquiry command.
63 * The following (VPD) pages are currently supported:
66 * - Unit Serial Number
67 * - Device Identification
70 #if !defined(DISABLE_SATI_INQUIRY)
72 #include <dev/isci/scil/sati_inquiry.h>
73 #include <dev/isci/scil/sati_callbacks.h>
74 #include <dev/isci/scil/sati_util.h>
75 #include <dev/isci/scil/intel_ata.h>
76 #include <dev/isci/scil/intel_scsi.h>
78 //******************************************************************************
79 //* P R I V A T E M E T H O D S
80 //******************************************************************************
82 * @brief This method builds the SCSI data associated with the SATI product
83 * revision that is commonly used on the Standard inquiry response and
84 * the ATA information page.
86 * @param[in] sequence This parameter specifies the translator sequence
87 * object to be utilized during data translation.
88 * @param[in] ata_input_data This parameter specifies ata data received from
90 * @param[out] scsi_io This parameter specifies the user IO request for
91 * which to construct the standard inquiry data.
96 void sati_inquiry_construct_product_revision(
97 SATI_TRANSLATOR_SEQUENCE_T * sequence,
98 void * ata_input_data,
102 ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
105 // Fill in the product revision level field.
106 // Per SAT, copy portions of the firmware revision that is not filled
107 // with spaces. Some devices left-align their firmware rev ID, while
108 // others right-align.
109 if ( (identify->firmware_revision[4] == 0x20)
110 && (identify->firmware_revision[5] == 0x20)
111 && (identify->firmware_revision[6] == 0x20)
112 && (identify->firmware_revision[7] == 0x20) )
114 sati_ata_identify_device_copy_data(
119 ATA_IDENTIFY_DEVICE_GET_OFFSET(firmware_revision),
126 // Since the last 4 bytes of the firmware revision are not spaces,
127 // utilize these bytes as the firmware revision in the inquiry data.
128 sati_ata_identify_device_copy_data(
133 ATA_IDENTIFY_DEVICE_GET_OFFSET(firmware_revision)+4,
141 //******************************************************************************
142 //* P U B L I C M E T H O D S
143 //******************************************************************************
146 * @brief This method builds the SCSI data associated with a SCSI standard
149 * @param[in] sequence This parameter specifies the translator sequence
150 * object to be utilized during data translation.
151 * @param[in] ata_input_data This parameter specifies ata data received from
153 * @param[out] scsi_io This parameter specifies the user IO request for
154 * which to construct the standard inquiry data.
158 void sati_inquiry_standard_translate_data(
159 SATI_TRANSLATOR_SEQUENCE_T * sequence,
160 void * ata_input_data,
164 ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
168 // Device type is disk, attached to this lun.
169 sati_set_data_byte(sequence, scsi_io, 0, 0x00);
171 // If the device indicates it's a removable media device, then set the
173 if (identify->general_config_bits & ATA_IDENTIFY_REMOVABLE_MEDIA_ENABLE)
174 sati_set_data_byte(sequence, scsi_io, 1, 0x80);
176 sati_set_data_byte(sequence, scsi_io, 1, 0x00);
178 sati_set_data_byte(sequence, scsi_io, 2, 0x05); // Indicate SPC-3 support
179 sati_set_data_byte(sequence, scsi_io, 3, 0x02); // Response Format SPC-3
181 sati_set_data_byte(sequence, scsi_io, 4, 62); // 62 Additional Data Bytes.
182 // n-4 per the spec, we end at
184 sati_set_data_byte(sequence, scsi_io, 5, 0x00);
185 sati_set_data_byte(sequence, scsi_io, 6, 0x00);
186 sati_set_data_byte(sequence, scsi_io, 7, 0x02); // Enable Cmd Queueing
188 // The Vender identification field is set to "ATA "
189 sati_set_data_byte(sequence, scsi_io, 8, 0x41);
190 sati_set_data_byte(sequence, scsi_io, 9, 0x54);
191 sati_set_data_byte(sequence, scsi_io, 10, 0x41);
192 sati_set_data_byte(sequence, scsi_io, 11, 0x20);
193 sati_set_data_byte(sequence, scsi_io, 12, 0x20);
194 sati_set_data_byte(sequence, scsi_io, 13, 0x20);
195 sati_set_data_byte(sequence, scsi_io, 14, 0x20);
196 sati_set_data_byte(sequence, scsi_io, 15, 0x20);
198 // Fill in the product ID field.
199 sati_ata_identify_device_copy_data(
204 ATA_IDENTIFY_DEVICE_GET_OFFSET(model_number),
209 sati_inquiry_construct_product_revision(
215 // Set the remaining fields up to the version descriptors to 0.
216 for (index = 36; index < 58; index++)
217 sati_set_data_byte(sequence, scsi_io, index, 0);
219 // Add version descriptors for the various protocols in play.
222 sati_set_data_byte(sequence, scsi_io, 58, 0);
223 sati_set_data_byte(sequence, scsi_io, 59, 0x80);
226 sati_set_data_byte(sequence, scsi_io, 60, 0x0C);
227 sati_set_data_byte(sequence, scsi_io, 61, 0x20);
230 sati_set_data_byte(sequence, scsi_io, 62, 0x04);
231 sati_set_data_byte(sequence, scsi_io, 63, 0x60);
234 sati_set_data_byte(sequence, scsi_io, 64, 0x04);
235 sati_set_data_byte(sequence, scsi_io, 65, 0xC0);
238 sati_set_data_byte(sequence, scsi_io, 66, 0x16);
239 sati_set_data_byte(sequence, scsi_io, 67, 0x23);
243 * @brief This method builds the SCSI data associated with an SCSI inquiry
244 * for the supported VPD pages page.
246 * @param[in] sequence This parameter specifies the translator sequence
247 * object to be utilized during data translation.
248 * @param[out] scsi_io This parameter specifies the user IO request for
249 * which to construct the supported VPD page information.
254 void sati_inquiry_supported_pages_translate_data(
255 SATI_TRANSLATOR_SEQUENCE_T * sequence,
259 // Formulate the SCSI output data for the caller.
260 sati_set_data_byte(sequence, scsi_io, 0, 0); // Qualifier and Device Type
261 sati_set_data_byte(sequence, scsi_io, 1, SCSI_INQUIRY_SUPPORTED_PAGES_PAGE);
262 sati_set_data_byte(sequence, scsi_io, 2, 0); // Reserved.
263 sati_set_data_byte(sequence, scsi_io, 3, 4); // # VPD pages supported
264 sati_set_data_byte(sequence, scsi_io, 4, SCSI_INQUIRY_SUPPORTED_PAGES_PAGE);
265 sati_set_data_byte(sequence, scsi_io, 5, SCSI_INQUIRY_UNIT_SERIAL_NUM_PAGE);
266 sati_set_data_byte(sequence, scsi_io, 6, SCSI_INQUIRY_DEVICE_ID_PAGE);
267 sati_set_data_byte(sequence, scsi_io, 7, SCSI_INQUIRY_ATA_INFORMATION_PAGE);
268 sati_set_data_byte(sequence, scsi_io, 8, SCSI_INQUIRY_BLOCK_DEVICE_PAGE);
269 sati_set_data_byte(sequence, scsi_io, 9, 0); // End of the list
273 * @brief This method builds the SCSI data associated with a request for
274 * the unit serial number vital product data (VPD) page.
276 * @param[in] sequence This parameter specifies the translator sequence
277 * object to be utilized during data translation.
278 * @param[in] ata_input_data This parameter specifies ata data received from
280 * @param[out] scsi_io This parameter specifies the user IO request for
281 * which to construct the unit serial number data.
285 void sati_inquiry_serial_number_translate_data(
286 SATI_TRANSLATOR_SEQUENCE_T * sequence,
287 void * ata_input_data,
291 // Peripheral qualifier (0x0, currently connected)
292 // Peripheral device type (0x0 direct-access block device)
293 sati_set_data_byte(sequence, scsi_io, 0, 0x00);
295 sati_set_data_byte(sequence, scsi_io, 1, SCSI_INQUIRY_UNIT_SERIAL_NUM_PAGE);
296 sati_set_data_byte(sequence, scsi_io, 2, 0x00); // Reserved
297 sati_set_data_byte(sequence, scsi_io, 3, ATA_IDENTIFY_SERIAL_NUMBER_LEN);
299 sati_ata_identify_device_copy_data(
304 ATA_IDENTIFY_DEVICE_GET_OFFSET(serial_number),
305 ATA_IDENTIFY_SERIAL_NUMBER_LEN,
311 * @brief This method builds the SCSI data associated with a request for
312 * the Block Device Characteristics vital product data (VPD) page.
314 * @param[in] sequence This parameter specifies the translator sequence
315 * object to be utilized during data translation.
316 * @param[in] ata_input_data This parameter specifies ata data received from
318 * @param[out] scsi_io This parameter specifies the user IO request for
319 * which to construct the unit serial number data.
323 void sati_inquiry_block_device_translate_data(
324 SATI_TRANSLATOR_SEQUENCE_T * sequence,
325 void * ata_input_data,
329 ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
334 // Peripheral qualifier (0x0, currently connected)
335 // Peripheral device type (0x0 direct-access block device)
336 sati_set_data_byte(sequence, scsi_io, 0, 0x00);
338 sati_set_data_byte(sequence, scsi_io, 1, SCSI_INQUIRY_BLOCK_DEVICE_PAGE);
341 sati_set_data_byte(sequence, scsi_io, 2, 0x00);
342 sati_set_data_byte(sequence, scsi_io, 3, SCSI_INQUIRY_BLOCK_DEVICE_LENGTH);
344 sati_ata_identify_device_copy_data(
349 ATA_IDENTIFY_DEVICE_GET_OFFSET(nominal_media_rotation_rate),
354 sati_set_data_byte(sequence, scsi_io, 6, 0x00);
360 (identify->device_nominal_form_factor & 0x0F) // only need bits 0-3
363 //bytes 8-63 are reserved
364 for(offset = 8; offset < 64; offset++)
366 sati_set_data_byte(sequence, scsi_io, offset, 0x00);
371 * @brief This method builds the SCSI data associated with a request for
372 * the device identification vital product data (VPD) page.
374 * @param[in] sequence This parameter specifies the translator sequence
375 * object to be utilized during data translation.
376 * @param[in] ata_input_data This parameter specifies ata data received from
378 * @param[out] scsi_io This parameter specifies the user IO request for
379 * which to construct the device ID page.
383 void sati_inquiry_device_id_translate_data(
384 SATI_TRANSLATOR_SEQUENCE_T * sequence,
385 void * ata_input_data,
389 ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
394 // Peripheral qualifier (0x0, currently connected)
395 // Peripheral device type (0x0 direct-access block device)
396 sati_set_data_byte(sequence, scsi_io, 0, 0x00);
398 sati_set_data_byte(sequence, scsi_io, 1, SCSI_INQUIRY_DEVICE_ID_PAGE);
401 * If World Wide Names are supported by this target, then build an
402 * identification descriptor using the WWN.
405 if (identify->command_set_supported_extention
406 & ATA_IDENTIFY_COMMAND_SET_WWN_SUPPORT_ENABLE)
409 sati_set_data_byte(sequence,
410 scsi_io, 4, SCSI_FC_PROTOCOL_IDENTIFIER | SCSI_BINARY_CODE_SET
414 sati_set_data_byte(sequence,
415 scsi_io, 5, SCSI_LUN_ASSOCIATION | SCSI_NAA_IDENTIFIER_TYPE
418 sati_set_data_byte(sequence, scsi_io, 6, 0);
419 sati_set_data_byte(sequence, scsi_io, 7, 0x08); // WWN are 8 bytes long
421 // Copy data from the identify device world wide name field into the
423 sati_ata_identify_device_copy_data(
428 ATA_IDENTIFY_DEVICE_GET_OFFSET(world_wide_name),
429 ATA_IDENTIFY_WWN_LEN,
437 * Build a identification descriptor using the model number & serial number.
440 sati_set_data_byte(sequence,
441 scsi_io, byte_offset, SCSI_FC_PROTOCOL_IDENTIFIER | SCSI_ASCII_CODE_SET
444 sati_set_data_byte(sequence,
445 scsi_io, byte_offset, SCSI_LUN_ASSOCIATION | SCSI_T10_IDENTIFIER_TYPE
448 sati_set_data_byte(sequence, scsi_io, byte_offset, 0);
451 // Identifier length (8 bytes for "ATA " + 40 bytes from ATA IDENTIFY
452 // model number field + 20 bytes from ATA IDENTIFY serial number field.
457 8 + (ATA_IDENTIFY_SERIAL_NUMBER_LEN) + (ATA_IDENTIFY_MODEL_NUMBER_LEN)
461 // Per SAT, write "ATA ".
462 sati_set_data_byte(sequence, scsi_io, byte_offset, 0x41);
464 sati_set_data_byte(sequence, scsi_io, byte_offset, 0x54);
466 sati_set_data_byte(sequence, scsi_io, byte_offset, 0x41);
468 sati_set_data_byte(sequence, scsi_io, byte_offset, 0x20);
470 sati_set_data_byte(sequence, scsi_io, byte_offset, 0x20);
472 sati_set_data_byte(sequence, scsi_io, byte_offset, 0x20);
474 sati_set_data_byte(sequence, scsi_io, byte_offset, 0x20);
476 sati_set_data_byte(sequence, scsi_io, byte_offset, 0x20);
479 // Copy data from the identify device model number field into the
480 // buffer and update the byte_offset.
481 sati_ata_identify_device_copy_data(
486 ATA_IDENTIFY_DEVICE_GET_OFFSET(model_number),
487 ATA_IDENTIFY_MODEL_NUMBER_LEN,
491 byte_offset += ATA_IDENTIFY_MODEL_NUMBER_LEN;
493 // Copy data from the identify device serial number field into the
494 // buffer and update the byte_offset.
495 sati_ata_identify_device_copy_data(
500 ATA_IDENTIFY_DEVICE_GET_OFFSET(serial_number),
501 ATA_IDENTIFY_SERIAL_NUMBER_LEN,
505 byte_offset += ATA_IDENTIFY_SERIAL_NUMBER_LEN;
508 * If the target is contained in a SAS Domain, then build a target port
509 * ID descriptor using the SAS address.
512 #if defined(SATI_TRANSPORT_SUPPORTS_SAS) \
513 && defined(DISABLE_MSFT_SCSI_COMPLIANCE_SUPPORT)
515 SCI_SAS_ADDRESS_T sas_address;
521 SCSI_SAS_PROTOCOL_IDENTIFIER | SCSI_BINARY_CODE_SET
529 SCSI_PIV_ENABLE | SCSI_TARGET_PORT_ASSOCIATION |
530 SCSI_NAA_IDENTIFIER_TYPE
534 sati_set_data_byte(sequence, scsi_io, byte_offset, 0);
536 sati_set_data_byte(sequence, scsi_io, byte_offset, 8); // SAS Addr=8 bytes
539 sati_cb_device_get_sas_address(scsi_io, &sas_address);
541 // Store the SAS address in the target port descriptor.
542 sati_set_data_dword(sequence, scsi_io, byte_offset, sas_address.high);
544 sati_set_data_dword(sequence, scsi_io, byte_offset, sas_address.low);
547 #endif // SATI_TRANSPORT_SUPPORTS_SAS && DISABLE_MSFT_SCSI_COMPLIANCE_SUPPORT
550 * Set the Page length field. The page length is n-3, where n is the
551 * last offset in the page (considered page length - 4).
554 page_length = byte_offset - 4;
555 sati_set_data_byte(sequence, scsi_io, 2, (U8)((page_length & 0xFF00) >> 8));
556 sati_set_data_byte(sequence, scsi_io, 3, (U8)(page_length & 0x00FF));
560 * @brief This method builds the SCSI data associated with a request for
561 * the ATA information vital product data (VPD) page.
563 * @param[in] sequence This parameter specifies the translator sequence
564 * object to be utilized during data translation.
565 * @param[in] ata_input_data This parameter specifies ata data received from
566 * a identify device command processed by the remote device.
567 * @param[out] scsi_io This parameter specifies the user IO request for
568 * which to construct the ATA information page.
572 SATI_STATUS sati_inquiry_ata_information_translate_data(
573 SATI_TRANSLATOR_SEQUENCE_T * sequence,
574 void * ata_input_data,
578 sati_set_data_byte(sequence, scsi_io, 0, 0x00);
579 sati_set_data_byte(sequence, scsi_io, 1, SCSI_INQUIRY_ATA_INFORMATION_PAGE);
580 sati_set_data_byte(sequence, scsi_io, 2, 0x02);
581 sati_set_data_byte(sequence, scsi_io, 3, 0x38);
584 sati_set_data_byte(sequence, scsi_io, 4, 0x00);
585 sati_set_data_byte(sequence, scsi_io, 5, 0x00);
586 sati_set_data_byte(sequence, scsi_io, 6, 0x00);
587 sati_set_data_byte(sequence, scsi_io, 7, 0x00);
589 // The Vender identification field is set to "ATA "
590 sati_set_data_byte(sequence, scsi_io, 8, 0x41);
591 sati_set_data_byte(sequence, scsi_io, 9, 0x54);
592 sati_set_data_byte(sequence, scsi_io, 10, 0x41);
593 sati_set_data_byte(sequence, scsi_io, 11, 0x20);
594 sati_set_data_byte(sequence, scsi_io, 12, 0x20);
595 sati_set_data_byte(sequence, scsi_io, 13, 0x20);
596 sati_set_data_byte(sequence, scsi_io, 14, 0x20);
597 sati_set_data_byte(sequence, scsi_io, 15, 0x20);
599 //SAT Product identification
600 sati_ata_identify_device_copy_data(
605 ATA_IDENTIFY_DEVICE_GET_OFFSET(model_number),
610 //SAT Product Revision level bytes 32-35
611 sati_inquiry_construct_product_revision(
617 //skipping ATA device signature for now
620 sati_set_data_byte(sequence, scsi_io, 56, 0xEC);
623 sati_set_data_byte(sequence, scsi_io, 57, 0x00);
624 sati_set_data_byte(sequence, scsi_io, 58, 0x00);
625 sati_set_data_byte(sequence, scsi_io, 59, 0x00);
627 //copy all ATA identify device data
628 sati_ata_identify_device_copy_data(
634 sizeof(ATA_IDENTIFY_DEVICE_DATA_T),
638 //Need to send ATA Execute Device Diagnostic command still
639 sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE;
641 return SATI_SEQUENCE_INCOMPLETE;
645 * @brief This method will translate the inquiry SCSI command into
646 * an ATA IDENTIFY DEVICE command. It will handle several different
647 * VPD pages and the standard inquiry page.
648 * For more information on the parameters passed to this method,
649 * please reference sati_translate_command().
651 * @return Indicate if the command translation succeeded.
652 * @retval SCI_SUCCESS This is returned if the command translation was
654 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
655 * the page isn't supported, or the page code
656 * field is not zero when the EVPD bit is 0.
658 SATI_STATUS sati_inquiry_translate_command(
659 SATI_TRANSLATOR_SEQUENCE_T * sequence,
664 U8 * cdb = sati_cb_get_cdb_address(scsi_io);
668 * - that the page code field must be 0, if VPD enable is 0.
670 if ( ((sati_get_cdb_byte(cdb, 1) & SCSI_INQUIRY_EVPD_ENABLE) == 0)
671 && (sati_get_cdb_byte(cdb, 2) != 0) )
673 sati_scsi_sense_data_construct(
676 SCSI_STATUS_CHECK_CONDITION,
677 SCSI_SENSE_ILLEGAL_REQUEST,
678 SCSI_ASC_INVALID_FIELD_IN_CDB,
679 SCSI_ASCQ_INVALID_FIELD_IN_CDB
681 return SATI_FAILURE_CHECK_RESPONSE_DATA;
684 // Set the data length based on the allocation length field in the CDB.
685 sequence->allocation_length = (sati_get_cdb_byte(cdb, 3) << 8) |
686 (sati_get_cdb_byte(cdb, 4));
688 // Check to see if there was a request for the vital product data or just
689 // the standard inquiry.
690 if (sati_get_cdb_byte(cdb, 1) & SCSI_INQUIRY_EVPD_ENABLE)
692 // Parse the page code to determine which translator to invoke.
693 switch (sati_get_cdb_byte(cdb, 2))
695 case SCSI_INQUIRY_SUPPORTED_PAGES_PAGE:
696 sequence->type = SATI_SEQUENCE_INQUIRY_SUPPORTED_PAGES;
697 sati_inquiry_supported_pages_translate_data(sequence, scsi_io);
698 return SATI_COMPLETE;
701 case SCSI_INQUIRY_UNIT_SERIAL_NUM_PAGE:
702 sequence->type = SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER;
705 case SCSI_INQUIRY_DEVICE_ID_PAGE:
706 sequence->type = SATI_SEQUENCE_INQUIRY_DEVICE_ID;
709 case SCSI_INQUIRY_ATA_INFORMATION_PAGE:
711 if(sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE)
713 sati_ata_execute_device_diagnostic_construct(
717 sequence->type = SATI_SEQUENCE_INQUIRY_EXECUTE_DEVICE_DIAG;
721 sequence->type = SATI_SEQUENCE_INQUIRY_ATA_INFORMATION;
725 case SCSI_INQUIRY_BLOCK_DEVICE_PAGE:
726 sequence->type = SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE;
730 sati_scsi_sense_data_construct(
733 SCSI_STATUS_CHECK_CONDITION,
734 SCSI_SENSE_ILLEGAL_REQUEST,
735 SCSI_ASC_INVALID_FIELD_IN_CDB,
736 SCSI_ASCQ_INVALID_FIELD_IN_CDB
738 return SATI_FAILURE_CHECK_RESPONSE_DATA;
744 sequence->type = SATI_SEQUENCE_INQUIRY_STANDARD;
747 sati_ata_identify_device_construct(ata_io, sequence);
753 * @brief This method finishes the construction of the SCSI data associated
754 with a request for the ATA information vital product data (VPD) page.
755 The ATA device signature is written into the data response from the
756 task fle registers after issuing a Execute Device Diagnostic command.
758 * @param[in] sequence This parameter specifies the translator sequence
759 * object to be utilized during data translation.
760 * @param[out] scsi_io This parameter specifies the user IO request for
761 * which to construct the ATA information page.
762 * @param[in] ata_io This parameter specifies the ATA payload
763 * buffer location and size to be translated.
767 void sati_inquiry_ata_information_finish_translation(
768 SATI_TRANSLATOR_SEQUENCE_T * sequence,
773 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
777 sati_set_data_byte(sequence, scsi_io, 36, 0x34);
778 sati_set_data_byte(sequence, scsi_io, 37, 0x00);
779 sati_set_data_byte(sequence, scsi_io, 38, (U8) sati_get_ata_status(register_fis));
780 sati_set_data_byte(sequence, scsi_io, 39, (U8) sati_get_ata_error(register_fis));
781 sati_set_data_byte(sequence, scsi_io, 40, sati_get_ata_lba_low(register_fis));
782 sati_set_data_byte(sequence, scsi_io, 41, sati_get_ata_lba_mid(register_fis));
783 sati_set_data_byte(sequence, scsi_io, 42, sati_get_ata_lba_high(register_fis));
784 sati_set_data_byte(sequence, scsi_io, 43, sati_get_ata_device(register_fis));
785 sati_set_data_byte(sequence, scsi_io, 44, sati_get_ata_lba_low_ext(register_fis));
786 sati_set_data_byte(sequence, scsi_io, 45, sati_get_ata_lba_mid_ext(register_fis));
787 sati_set_data_byte(sequence, scsi_io, 46, sati_get_ata_lba_high_ext(register_fis));
788 sati_set_data_byte(sequence, scsi_io, 47, 0x00);
789 sati_set_data_byte(sequence, scsi_io, 48, sati_get_ata_sector_count(register_fis));
790 sati_set_data_byte(sequence, scsi_io, 49, sati_get_ata_sector_count_exp(register_fis));
792 for(offset = 50; offset < 56; offset++)
794 sati_set_data_byte(sequence, scsi_io, offset, 0x00);
797 sequence->state = SATI_SEQUENCE_STATE_FINAL;
800 #endif // !defined(DISABLE_SATI_INQUIRY)