xref: /freebsd/sys/dev/isci/scil/sati_inquiry.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
1f11c7f63SJim Harris /*-
2*718cf2ccSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3*718cf2ccSPedro F. Giffuni  *
4f11c7f63SJim Harris  * This file is provided under a dual BSD/GPLv2 license.  When using or
5f11c7f63SJim Harris  * redistributing this file, you may do so under either license.
6f11c7f63SJim Harris  *
7f11c7f63SJim Harris  * GPL LICENSE SUMMARY
8f11c7f63SJim Harris  *
9f11c7f63SJim Harris  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
10f11c7f63SJim Harris  *
11f11c7f63SJim Harris  * This program is free software; you can redistribute it and/or modify
12f11c7f63SJim Harris  * it under the terms of version 2 of the GNU General Public License as
13f11c7f63SJim Harris  * published by the Free Software Foundation.
14f11c7f63SJim Harris  *
15f11c7f63SJim Harris  * This program is distributed in the hope that it will be useful, but
16f11c7f63SJim Harris  * WITHOUT ANY WARRANTY; without even the implied warranty of
17f11c7f63SJim Harris  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18f11c7f63SJim Harris  * General Public License for more details.
19f11c7f63SJim Harris  *
20f11c7f63SJim Harris  * You should have received a copy of the GNU General Public License
21f11c7f63SJim Harris  * along with this program; if not, write to the Free Software
22f11c7f63SJim Harris  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23f11c7f63SJim Harris  * The full GNU General Public License is included in this distribution
24f11c7f63SJim Harris  * in the file called LICENSE.GPL.
25f11c7f63SJim Harris  *
26f11c7f63SJim Harris  * BSD LICENSE
27f11c7f63SJim Harris  *
28f11c7f63SJim Harris  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29f11c7f63SJim Harris  * All rights reserved.
30f11c7f63SJim Harris  *
31f11c7f63SJim Harris  * Redistribution and use in source and binary forms, with or without
32f11c7f63SJim Harris  * modification, are permitted provided that the following conditions
33f11c7f63SJim Harris  * are met:
34f11c7f63SJim Harris  *
35f11c7f63SJim Harris  *   * Redistributions of source code must retain the above copyright
36f11c7f63SJim Harris  *     notice, this list of conditions and the following disclaimer.
37f11c7f63SJim Harris  *   * Redistributions in binary form must reproduce the above copyright
38f11c7f63SJim Harris  *     notice, this list of conditions and the following disclaimer in
39f11c7f63SJim Harris  *     the documentation and/or other materials provided with the
40f11c7f63SJim Harris  *     distribution.
41f11c7f63SJim Harris  *
42f11c7f63SJim Harris  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43f11c7f63SJim Harris  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44f11c7f63SJim Harris  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45f11c7f63SJim Harris  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46f11c7f63SJim Harris  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47f11c7f63SJim Harris  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48f11c7f63SJim Harris  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49f11c7f63SJim Harris  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50f11c7f63SJim Harris  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51f11c7f63SJim Harris  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52f11c7f63SJim Harris  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53f11c7f63SJim Harris  */
54f11c7f63SJim Harris 
55f11c7f63SJim Harris #include <sys/cdefs.h>
56f11c7f63SJim Harris /**
57f11c7f63SJim Harris  * @file
58f11c7f63SJim Harris  *
59f11c7f63SJim Harris  * @brief This file contains the method implementations required to
60f11c7f63SJim Harris  *        translate the SCSI inquiry command.
61f11c7f63SJim Harris  *        The following (VPD) pages are currently supported:
62f11c7f63SJim Harris  *        - Standard
63f11c7f63SJim Harris  *        - Supported Pages
64f11c7f63SJim Harris  *        - Unit Serial Number
65f11c7f63SJim Harris  *        - Device Identification
66f11c7f63SJim Harris  */
67f11c7f63SJim Harris 
68f11c7f63SJim Harris #if !defined(DISABLE_SATI_INQUIRY)
69f11c7f63SJim Harris 
70f11c7f63SJim Harris #include <dev/isci/scil/sati_inquiry.h>
71f11c7f63SJim Harris #include <dev/isci/scil/sati_callbacks.h>
72f11c7f63SJim Harris #include <dev/isci/scil/sati_util.h>
73f11c7f63SJim Harris #include <dev/isci/scil/intel_ata.h>
74f11c7f63SJim Harris #include <dev/isci/scil/intel_scsi.h>
75f11c7f63SJim Harris 
76f11c7f63SJim Harris //******************************************************************************
77f11c7f63SJim Harris //* P R I V A T E   M E T H O D S
78f11c7f63SJim Harris //******************************************************************************
79f11c7f63SJim Harris /**
80f11c7f63SJim Harris * @brief This method builds the SCSI data associated with the SATI product
81f11c7f63SJim Harris *        revision that is commonly used on the Standard inquiry response and
82f11c7f63SJim Harris *        the ATA information page.
83f11c7f63SJim Harris *
84f11c7f63SJim Harris * @param[in]  sequence This parameter specifies the translator sequence
85f11c7f63SJim Harris *             object to be utilized during data translation.
86f11c7f63SJim Harris * @param[in]  ata_input_data This parameter specifies ata data received from
87f11c7f63SJim Harris *             the remote device.
88f11c7f63SJim Harris * @param[out] scsi_io This parameter specifies the user IO request for
89f11c7f63SJim Harris *             which to construct the standard inquiry data.
90f11c7f63SJim Harris *
91f11c7f63SJim Harris * @return none
92f11c7f63SJim Harris */
93f11c7f63SJim Harris static
sati_inquiry_construct_product_revision(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * ata_input_data,void * scsi_io)94f11c7f63SJim Harris void sati_inquiry_construct_product_revision(
95f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
96f11c7f63SJim Harris    void                       * ata_input_data,
97f11c7f63SJim Harris    void                       * scsi_io
98f11c7f63SJim Harris )
99f11c7f63SJim Harris {
100f11c7f63SJim Harris    ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
101f11c7f63SJim Harris       ata_input_data;
102f11c7f63SJim Harris 
103f11c7f63SJim Harris    // Fill in the product revision level field.
104f11c7f63SJim Harris    // Per SAT, copy portions of the firmware revision that is not filled
105f11c7f63SJim Harris    // with spaces.  Some devices left-align their firmware rev ID, while
106f11c7f63SJim Harris    // others right-align.
107f11c7f63SJim Harris    if (  (identify->firmware_revision[4] == 0x20)
108f11c7f63SJim Harris        && (identify->firmware_revision[5] == 0x20)
109f11c7f63SJim Harris        && (identify->firmware_revision[6] == 0x20)
110f11c7f63SJim Harris        && (identify->firmware_revision[7] == 0x20) )
111f11c7f63SJim Harris    {
112f11c7f63SJim Harris       sati_ata_identify_device_copy_data(
113f11c7f63SJim Harris          sequence,
114f11c7f63SJim Harris          scsi_io,
115f11c7f63SJim Harris          32,
116f11c7f63SJim Harris          ata_input_data,
117f11c7f63SJim Harris          ATA_IDENTIFY_DEVICE_GET_OFFSET(firmware_revision),
118f11c7f63SJim Harris          4,
119f11c7f63SJim Harris          TRUE
120f11c7f63SJim Harris        );
121f11c7f63SJim Harris    }
122f11c7f63SJim Harris    else
123f11c7f63SJim Harris    {
124f11c7f63SJim Harris       // Since the last 4 bytes of the firmware revision are not spaces,
125f11c7f63SJim Harris       // utilize these bytes as the firmware revision in the inquiry data.
126f11c7f63SJim Harris       sati_ata_identify_device_copy_data(
127f11c7f63SJim Harris          sequence,
128f11c7f63SJim Harris          scsi_io,
129f11c7f63SJim Harris          32,
130f11c7f63SJim Harris          ata_input_data,
131f11c7f63SJim Harris          ATA_IDENTIFY_DEVICE_GET_OFFSET(firmware_revision)+4,
132f11c7f63SJim Harris          4,
133f11c7f63SJim Harris          TRUE
134f11c7f63SJim Harris       );
135f11c7f63SJim Harris    }
136f11c7f63SJim Harris }
137f11c7f63SJim Harris 
138f11c7f63SJim Harris 
139f11c7f63SJim Harris //******************************************************************************
140f11c7f63SJim Harris //* P U B L I C   M E T H O D S
141f11c7f63SJim Harris //******************************************************************************
142f11c7f63SJim Harris 
143f11c7f63SJim Harris /**
144f11c7f63SJim Harris  * @brief This method builds the SCSI data associated with a SCSI standard
145f11c7f63SJim Harris  *        inquiry request.
146f11c7f63SJim Harris  *
147f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
148f11c7f63SJim Harris  *             object to be utilized during data translation.
149f11c7f63SJim Harris  * @param[in]  ata_input_data This parameter specifies ata data received from
150f11c7f63SJim Harris  *             the remote device.
151f11c7f63SJim Harris  * @param[out] scsi_io This parameter specifies the user IO request for
152f11c7f63SJim Harris  *             which to construct the standard inquiry data.
153f11c7f63SJim Harris  *
154f11c7f63SJim Harris  * @return none
155f11c7f63SJim Harris  */
sati_inquiry_standard_translate_data(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * ata_input_data,void * scsi_io)156f11c7f63SJim Harris void sati_inquiry_standard_translate_data(
157f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
158f11c7f63SJim Harris    void                       * ata_input_data,
159f11c7f63SJim Harris    void                       * scsi_io
160f11c7f63SJim Harris )
161f11c7f63SJim Harris {
162f11c7f63SJim Harris    ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
163f11c7f63SJim Harris                                            ata_input_data;
164f11c7f63SJim Harris    U32  index;
165f11c7f63SJim Harris 
166f11c7f63SJim Harris    // Device type is disk, attached to this lun.
167f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 0, 0x00);
168f11c7f63SJim Harris 
169f11c7f63SJim Harris    // If the device indicates it's a removable media device, then set the
170f11c7f63SJim Harris    // RMB bit
171f11c7f63SJim Harris    if (identify->general_config_bits & ATA_IDENTIFY_REMOVABLE_MEDIA_ENABLE)
172f11c7f63SJim Harris       sati_set_data_byte(sequence, scsi_io, 1, 0x80);
173f11c7f63SJim Harris    else
174f11c7f63SJim Harris       sati_set_data_byte(sequence, scsi_io, 1, 0x00);
175f11c7f63SJim Harris 
176f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 2, 0x05); // Indicate SPC-3 support
177f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 3, 0x02); // Response Format SPC-3
178f11c7f63SJim Harris 
179f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 4, 62); // 62 Additional Data Bytes.
180f11c7f63SJim Harris                                                  // n-4 per the spec, we end at
181f11c7f63SJim Harris                                                  // byte 66, so 66-4.
182f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 5, 0x00);
183f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 6, 0x00);
184f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 7, 0x02); // Enable Cmd Queueing
185f11c7f63SJim Harris 
186f11c7f63SJim Harris    // The Vender identification field is set to "ATA     "
187f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 8, 0x41);
188f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 9, 0x54);
189f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 10, 0x41);
190f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 11, 0x20);
191f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 12, 0x20);
192f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 13, 0x20);
193f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 14, 0x20);
194f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 15, 0x20);
195f11c7f63SJim Harris 
196f11c7f63SJim Harris    // Fill in the product ID field.
197f11c7f63SJim Harris    sati_ata_identify_device_copy_data(
198f11c7f63SJim Harris       sequence,
199f11c7f63SJim Harris       scsi_io,
200f11c7f63SJim Harris       16,
201f11c7f63SJim Harris       ata_input_data,
202f11c7f63SJim Harris       ATA_IDENTIFY_DEVICE_GET_OFFSET(model_number),
203f11c7f63SJim Harris       16,
204f11c7f63SJim Harris       TRUE
205f11c7f63SJim Harris    );
206f11c7f63SJim Harris 
207f11c7f63SJim Harris    sati_inquiry_construct_product_revision(
208f11c7f63SJim Harris       sequence,
209f11c7f63SJim Harris       ata_input_data,
210f11c7f63SJim Harris       scsi_io
211f11c7f63SJim Harris    );
212f11c7f63SJim Harris 
213f11c7f63SJim Harris    // Set the remaining fields up to the version descriptors to 0.
214f11c7f63SJim Harris    for (index = 36; index < 58; index++)
215f11c7f63SJim Harris       sati_set_data_byte(sequence, scsi_io, index, 0);
216f11c7f63SJim Harris 
217f11c7f63SJim Harris    // Add version descriptors for the various protocols in play.
218f11c7f63SJim Harris 
219f11c7f63SJim Harris    // SAM-4
220f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 58, 0);
221f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 59, 0x80);
222f11c7f63SJim Harris 
223f11c7f63SJim Harris    // SAS-2
224f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 60, 0x0C);
225f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 61, 0x20);
226f11c7f63SJim Harris 
227f11c7f63SJim Harris    // SPC-4
228f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 62, 0x04);
229f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 63, 0x60);
230f11c7f63SJim Harris 
231f11c7f63SJim Harris    // SBC-3
232f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 64, 0x04);
233f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 65, 0xC0);
234f11c7f63SJim Harris 
235f11c7f63SJim Harris    // ATA/ATAPI-8 ACS
236f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 66, 0x16);
237f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 67, 0x23);
238f11c7f63SJim Harris }
239f11c7f63SJim Harris 
240f11c7f63SJim Harris /**
241f11c7f63SJim Harris  * @brief This method builds the SCSI data associated with an SCSI inquiry
242f11c7f63SJim Harris  *        for the supported VPD pages page.
243f11c7f63SJim Harris  *
244f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
245f11c7f63SJim Harris  *             object to be utilized during data translation.
246f11c7f63SJim Harris  * @param[out] scsi_io This parameter specifies the user IO request for
247f11c7f63SJim Harris  *             which to construct the supported VPD page information.
248f11c7f63SJim Harris  *
249f11c7f63SJim Harris  * @return none
250f11c7f63SJim Harris  */
251f11c7f63SJim Harris static
sati_inquiry_supported_pages_translate_data(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io)252f11c7f63SJim Harris void sati_inquiry_supported_pages_translate_data(
253f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
254f11c7f63SJim Harris    void                       * scsi_io
255f11c7f63SJim Harris )
256f11c7f63SJim Harris {
257f11c7f63SJim Harris    // Formulate the SCSI output data for the caller.
258f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 0, 0); // Qualifier and Device Type
259f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 1, SCSI_INQUIRY_SUPPORTED_PAGES_PAGE);
260f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 2, 0); // Reserved.
261f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 3, 4); // # VPD pages supported
262f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 4, SCSI_INQUIRY_SUPPORTED_PAGES_PAGE);
263f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 5, SCSI_INQUIRY_UNIT_SERIAL_NUM_PAGE);
264f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 6, SCSI_INQUIRY_DEVICE_ID_PAGE);
265f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 7, SCSI_INQUIRY_ATA_INFORMATION_PAGE);
266f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 8, SCSI_INQUIRY_BLOCK_DEVICE_PAGE);
267f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 9, 0); // End of the list
268f11c7f63SJim Harris }
269f11c7f63SJim Harris 
270f11c7f63SJim Harris /**
271f11c7f63SJim Harris  * @brief This method builds the SCSI data associated with a request for
272f11c7f63SJim Harris  *        the unit serial number vital product data (VPD) page.
273f11c7f63SJim Harris  *
274f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
275f11c7f63SJim Harris  *             object to be utilized during data translation.
276f11c7f63SJim Harris  * @param[in]  ata_input_data This parameter specifies ata data received from
277f11c7f63SJim Harris  *             the remote device.
278f11c7f63SJim Harris  * @param[out] scsi_io This parameter specifies the user IO request for
279f11c7f63SJim Harris  *             which to construct the unit serial number data.
280f11c7f63SJim Harris  *
281f11c7f63SJim Harris  * @return none
282f11c7f63SJim Harris  */
sati_inquiry_serial_number_translate_data(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * ata_input_data,void * scsi_io)283f11c7f63SJim Harris void sati_inquiry_serial_number_translate_data(
284f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
285f11c7f63SJim Harris    void                       * ata_input_data,
286f11c7f63SJim Harris    void                       * scsi_io
287f11c7f63SJim Harris )
288f11c7f63SJim Harris {
289f11c7f63SJim Harris    // Peripheral qualifier (0x0, currently connected)
290f11c7f63SJim Harris    // Peripheral device type (0x0 direct-access block device)
291f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 0, 0x00);
292f11c7f63SJim Harris 
293f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 1, SCSI_INQUIRY_UNIT_SERIAL_NUM_PAGE);
294f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 2, 0x00);  // Reserved
295f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 3, ATA_IDENTIFY_SERIAL_NUMBER_LEN);
296f11c7f63SJim Harris 
297f11c7f63SJim Harris    sati_ata_identify_device_copy_data(
298f11c7f63SJim Harris       sequence,
299f11c7f63SJim Harris       scsi_io,
300f11c7f63SJim Harris       4,
301f11c7f63SJim Harris       ata_input_data,
302f11c7f63SJim Harris       ATA_IDENTIFY_DEVICE_GET_OFFSET(serial_number),
303f11c7f63SJim Harris       ATA_IDENTIFY_SERIAL_NUMBER_LEN,
304f11c7f63SJim Harris       TRUE
305f11c7f63SJim Harris    );
306f11c7f63SJim Harris }
307f11c7f63SJim Harris 
308f11c7f63SJim Harris /**
309f11c7f63SJim Harris * @brief This method builds the SCSI data associated with a request for
310f11c7f63SJim Harris *        the Block Device Characteristics vital product data (VPD) page.
311f11c7f63SJim Harris *
312f11c7f63SJim Harris * @param[in]  sequence This parameter specifies the translator sequence
313f11c7f63SJim Harris *             object to be utilized during data translation.
314f11c7f63SJim Harris * @param[in]  ata_input_data This parameter specifies ata data received from
315f11c7f63SJim Harris *             the remote device.
316f11c7f63SJim Harris * @param[out] scsi_io This parameter specifies the user IO request for
317f11c7f63SJim Harris *             which to construct the unit serial number data.
318f11c7f63SJim Harris *
319f11c7f63SJim Harris * @return none
320f11c7f63SJim Harris */
sati_inquiry_block_device_translate_data(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * ata_input_data,void * scsi_io)321f11c7f63SJim Harris void sati_inquiry_block_device_translate_data(
322f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
323f11c7f63SJim Harris    void                       * ata_input_data,
324f11c7f63SJim Harris    void                       * scsi_io
325f11c7f63SJim Harris )
326f11c7f63SJim Harris {
327f11c7f63SJim Harris    ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
328f11c7f63SJim Harris       ata_input_data;
329f11c7f63SJim Harris 
330f11c7f63SJim Harris    U32 offset;
331f11c7f63SJim Harris 
332f11c7f63SJim Harris    // Peripheral qualifier (0x0, currently connected)
333f11c7f63SJim Harris    // Peripheral device type (0x0 direct-access block device)
334f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 0, 0x00);
335f11c7f63SJim Harris 
336f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 1, SCSI_INQUIRY_BLOCK_DEVICE_PAGE);
337f11c7f63SJim Harris 
338f11c7f63SJim Harris    //PAGE LENGTH 0x003C
339f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 2, 0x00);
340f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 3, SCSI_INQUIRY_BLOCK_DEVICE_LENGTH);
341f11c7f63SJim Harris 
342f11c7f63SJim Harris    sati_ata_identify_device_copy_data(
343f11c7f63SJim Harris       sequence,
344f11c7f63SJim Harris       scsi_io,
345f11c7f63SJim Harris       4,
346f11c7f63SJim Harris       ata_input_data,
347f11c7f63SJim Harris       ATA_IDENTIFY_DEVICE_GET_OFFSET(nominal_media_rotation_rate),
348f11c7f63SJim Harris       2,
349f11c7f63SJim Harris       FALSE
350f11c7f63SJim Harris     );
351f11c7f63SJim Harris 
352f11c7f63SJim Harris     sati_set_data_byte(sequence, scsi_io, 6, 0x00);
353f11c7f63SJim Harris 
354f11c7f63SJim Harris     sati_set_data_byte(
355f11c7f63SJim Harris        sequence,
356f11c7f63SJim Harris        scsi_io,
357f11c7f63SJim Harris        7,
358f11c7f63SJim Harris        (identify->device_nominal_form_factor & 0x0F) // only need bits 0-3
359f11c7f63SJim Harris     );
360f11c7f63SJim Harris 
361f11c7f63SJim Harris     //bytes 8-63 are reserved
362e0e3e85dSJim Harris     for(offset = 8; offset < 64; offset++)
363f11c7f63SJim Harris     {
364f11c7f63SJim Harris        sati_set_data_byte(sequence, scsi_io, offset, 0x00);
365f11c7f63SJim Harris     }
366f11c7f63SJim Harris }
367f11c7f63SJim Harris 
368f11c7f63SJim Harris /**
369f11c7f63SJim Harris  * @brief This method builds the SCSI data associated with a request for
370f11c7f63SJim Harris  *        the device identification vital product data (VPD) page.
371f11c7f63SJim Harris  *
372f11c7f63SJim Harris  * @param[in]  sequence This parameter specifies the translator sequence
373f11c7f63SJim Harris  *             object to be utilized during data translation.
374f11c7f63SJim Harris  * @param[in]  ata_input_data This parameter specifies ata data received from
375f11c7f63SJim Harris  *             the remote device.
376f11c7f63SJim Harris  * @param[out] scsi_io This parameter specifies the user IO request for
377f11c7f63SJim Harris  *             which to construct the device ID page.
378f11c7f63SJim Harris  *
379f11c7f63SJim Harris  * @return none
380f11c7f63SJim Harris  */
sati_inquiry_device_id_translate_data(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * ata_input_data,void * scsi_io)381f11c7f63SJim Harris void sati_inquiry_device_id_translate_data(
382f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
383f11c7f63SJim Harris    void                       * ata_input_data,
384f11c7f63SJim Harris    void                       * scsi_io
385f11c7f63SJim Harris )
386f11c7f63SJim Harris {
387f11c7f63SJim Harris    ATA_IDENTIFY_DEVICE_DATA_T * identify    = (ATA_IDENTIFY_DEVICE_DATA_T*)
388f11c7f63SJim Harris                                               ata_input_data;
389f11c7f63SJim Harris    U16                     byte_offset = 4;
390f11c7f63SJim Harris    U16                     page_length;
391f11c7f63SJim Harris 
392f11c7f63SJim Harris    // Peripheral qualifier (0x0, currently connected)
393f11c7f63SJim Harris    // Peripheral device type (0x0 direct-access block device)
394f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 0, 0x00);
395f11c7f63SJim Harris 
396f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 1, SCSI_INQUIRY_DEVICE_ID_PAGE);
397f11c7f63SJim Harris 
398f11c7f63SJim Harris    /**
399f11c7f63SJim Harris     * If World Wide Names are supported by this target, then build an
400f11c7f63SJim Harris     * identification descriptor using the WWN.
401f11c7f63SJim Harris     */
402f11c7f63SJim Harris 
403f11c7f63SJim Harris    if (identify->command_set_supported_extention
404f11c7f63SJim Harris        & ATA_IDENTIFY_COMMAND_SET_WWN_SUPPORT_ENABLE)
405f11c7f63SJim Harris    {
406f11c7f63SJim Harris 
407f11c7f63SJim Harris       sati_set_data_byte(sequence,
408f11c7f63SJim Harris          scsi_io, 4, SCSI_FC_PROTOCOL_IDENTIFIER | SCSI_BINARY_CODE_SET
409f11c7f63SJim Harris       );
410f11c7f63SJim Harris 
411f11c7f63SJim Harris 
412f11c7f63SJim Harris       sati_set_data_byte(sequence,
413f11c7f63SJim Harris          scsi_io, 5, SCSI_LUN_ASSOCIATION | SCSI_NAA_IDENTIFIER_TYPE
414f11c7f63SJim Harris       );
415f11c7f63SJim Harris 
416f11c7f63SJim Harris       sati_set_data_byte(sequence, scsi_io, 6, 0);
417f11c7f63SJim Harris       sati_set_data_byte(sequence, scsi_io, 7, 0x08); // WWN are 8 bytes long
418f11c7f63SJim Harris 
419f11c7f63SJim Harris       // Copy data from the identify device world wide name field into the
420f11c7f63SJim Harris       // buffer.
421f11c7f63SJim Harris       sati_ata_identify_device_copy_data(
422f11c7f63SJim Harris          sequence,
423f11c7f63SJim Harris          scsi_io,
424f11c7f63SJim Harris          8,
425f11c7f63SJim Harris          ata_input_data,
426f11c7f63SJim Harris          ATA_IDENTIFY_DEVICE_GET_OFFSET(world_wide_name),
427f11c7f63SJim Harris          ATA_IDENTIFY_WWN_LEN,
428f11c7f63SJim Harris          FALSE
429f11c7f63SJim Harris       );
430f11c7f63SJim Harris 
431f11c7f63SJim Harris       byte_offset = 16;
432f11c7f63SJim Harris    }
433f11c7f63SJim Harris 
434f11c7f63SJim Harris    /**
435f11c7f63SJim Harris     * Build a identification descriptor using the model number & serial number.
436f11c7f63SJim Harris     */
437f11c7f63SJim Harris 
438f11c7f63SJim Harris    sati_set_data_byte(sequence,
439f11c7f63SJim Harris       scsi_io, byte_offset, SCSI_FC_PROTOCOL_IDENTIFIER | SCSI_ASCII_CODE_SET
440f11c7f63SJim Harris    );
441f11c7f63SJim Harris    byte_offset++;
442f11c7f63SJim Harris    sati_set_data_byte(sequence,
443f11c7f63SJim Harris       scsi_io, byte_offset, SCSI_LUN_ASSOCIATION | SCSI_T10_IDENTIFIER_TYPE
444f11c7f63SJim Harris    );
445f11c7f63SJim Harris    byte_offset++;
446f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, 0);
447f11c7f63SJim Harris    byte_offset++;
448f11c7f63SJim Harris 
449f11c7f63SJim Harris    // Identifier length (8 bytes for "ATA     " + 40 bytes from ATA IDENTIFY
450f11c7f63SJim Harris    // model number field + 20 bytes from ATA IDENTIFY serial number field.
451f11c7f63SJim Harris    sati_set_data_byte(
452f11c7f63SJim Harris       sequence,
453f11c7f63SJim Harris       scsi_io,
454f11c7f63SJim Harris       byte_offset,
455f11c7f63SJim Harris       8 + (ATA_IDENTIFY_SERIAL_NUMBER_LEN) + (ATA_IDENTIFY_MODEL_NUMBER_LEN)
456f11c7f63SJim Harris    );
457f11c7f63SJim Harris    byte_offset++;
458f11c7f63SJim Harris 
459f11c7f63SJim Harris    // Per SAT, write "ATA     ".
460f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, 0x41);
461f11c7f63SJim Harris    byte_offset++;
462f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, 0x54);
463f11c7f63SJim Harris    byte_offset++;
464f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, 0x41);
465f11c7f63SJim Harris    byte_offset++;
466f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, 0x20);
467f11c7f63SJim Harris    byte_offset++;
468f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, 0x20);
469f11c7f63SJim Harris    byte_offset++;
470f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, 0x20);
471f11c7f63SJim Harris    byte_offset++;
472f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, 0x20);
473f11c7f63SJim Harris    byte_offset++;
474f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, byte_offset, 0x20);
475f11c7f63SJim Harris    byte_offset++;
476f11c7f63SJim Harris 
477f11c7f63SJim Harris    // Copy data from the identify device model number field into the
478f11c7f63SJim Harris    // buffer and update the byte_offset.
479f11c7f63SJim Harris    sati_ata_identify_device_copy_data(
480f11c7f63SJim Harris       sequence,
481f11c7f63SJim Harris       scsi_io,
482f11c7f63SJim Harris       byte_offset,
483f11c7f63SJim Harris       ata_input_data,
484f11c7f63SJim Harris       ATA_IDENTIFY_DEVICE_GET_OFFSET(model_number),
485f11c7f63SJim Harris       ATA_IDENTIFY_MODEL_NUMBER_LEN,
486f11c7f63SJim Harris       TRUE
487f11c7f63SJim Harris    );
488f11c7f63SJim Harris 
489f11c7f63SJim Harris    byte_offset += ATA_IDENTIFY_MODEL_NUMBER_LEN;
490f11c7f63SJim Harris 
491f11c7f63SJim Harris    // Copy data from the identify device serial number field into the
492f11c7f63SJim Harris    // buffer and update the byte_offset.
493f11c7f63SJim Harris    sati_ata_identify_device_copy_data(
494f11c7f63SJim Harris       sequence,
495f11c7f63SJim Harris       scsi_io,
496f11c7f63SJim Harris       byte_offset,
497f11c7f63SJim Harris       ata_input_data,
498f11c7f63SJim Harris       ATA_IDENTIFY_DEVICE_GET_OFFSET(serial_number),
499f11c7f63SJim Harris       ATA_IDENTIFY_SERIAL_NUMBER_LEN,
500f11c7f63SJim Harris       TRUE
501f11c7f63SJim Harris    );
502f11c7f63SJim Harris 
503f11c7f63SJim Harris    byte_offset += ATA_IDENTIFY_SERIAL_NUMBER_LEN;
504f11c7f63SJim Harris 
505f11c7f63SJim Harris    /**
506f11c7f63SJim Harris     * If the target is contained in a SAS Domain, then build a target port
507f11c7f63SJim Harris     * ID descriptor using the SAS address.
508f11c7f63SJim Harris     */
509f11c7f63SJim Harris 
510f11c7f63SJim Harris #if     defined(SATI_TRANSPORT_SUPPORTS_SAS)       \
511f11c7f63SJim Harris      && defined(DISABLE_MSFT_SCSI_COMPLIANCE_SUPPORT)
512f11c7f63SJim Harris    {
513f11c7f63SJim Harris       SCI_SAS_ADDRESS_T sas_address;
514f11c7f63SJim Harris 
515f11c7f63SJim Harris       sati_set_data_byte(
516f11c7f63SJim Harris          sequence,
517f11c7f63SJim Harris          scsi_io,
518f11c7f63SJim Harris          byte_offset,
519f11c7f63SJim Harris          SCSI_SAS_PROTOCOL_IDENTIFIER | SCSI_BINARY_CODE_SET
520f11c7f63SJim Harris       );
521f11c7f63SJim Harris       byte_offset++;
522f11c7f63SJim Harris 
523f11c7f63SJim Harris       sati_set_data_byte(
524f11c7f63SJim Harris          sequence,
525f11c7f63SJim Harris          scsi_io,
526f11c7f63SJim Harris          byte_offset,
527f11c7f63SJim Harris          SCSI_PIV_ENABLE | SCSI_TARGET_PORT_ASSOCIATION |
528f11c7f63SJim Harris          SCSI_NAA_IDENTIFIER_TYPE
529f11c7f63SJim Harris       );
530f11c7f63SJim Harris 
531f11c7f63SJim Harris       byte_offset++;
532f11c7f63SJim Harris       sati_set_data_byte(sequence, scsi_io, byte_offset, 0);
533f11c7f63SJim Harris       byte_offset++;
534f11c7f63SJim Harris       sati_set_data_byte(sequence, scsi_io, byte_offset, 8); // SAS Addr=8 bytes
535f11c7f63SJim Harris       byte_offset++;
536f11c7f63SJim Harris 
537f11c7f63SJim Harris       sati_cb_device_get_sas_address(scsi_io, &sas_address);
538f11c7f63SJim Harris 
539f11c7f63SJim Harris       // Store the SAS address in the target port descriptor.
540f11c7f63SJim Harris       sati_set_data_dword(sequence, scsi_io, byte_offset, sas_address.high);
541f11c7f63SJim Harris       byte_offset += 4;
542f11c7f63SJim Harris       sati_set_data_dword(sequence, scsi_io, byte_offset, sas_address.low);
543f11c7f63SJim Harris       byte_offset += 4;
544f11c7f63SJim Harris    }
545f11c7f63SJim Harris #endif // SATI_TRANSPORT_SUPPORTS_SAS && DISABLE_MSFT_SCSI_COMPLIANCE_SUPPORT
546f11c7f63SJim Harris 
547f11c7f63SJim Harris    /**
548f11c7f63SJim Harris     * Set the Page length field.  The page length is n-3, where n is the
549f11c7f63SJim Harris     * last offset in the page (considered page length - 4).
550f11c7f63SJim Harris     */
551f11c7f63SJim Harris 
552f11c7f63SJim Harris    page_length = byte_offset - 4;
553f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 2, (U8)((page_length & 0xFF00) >> 8));
554f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 3, (U8)(page_length & 0x00FF));
555f11c7f63SJim Harris }
556f11c7f63SJim Harris 
557f11c7f63SJim Harris /**
558f11c7f63SJim Harris * @brief This method builds the SCSI data associated with a request for
559f11c7f63SJim Harris *        the  ATA information vital product data (VPD) page.
560f11c7f63SJim Harris *
561f11c7f63SJim Harris * @param[in]  sequence This parameter specifies the translator sequence
562f11c7f63SJim Harris *             object to be utilized during data translation.
563f11c7f63SJim Harris * @param[in]  ata_input_data This parameter specifies ata data received from
564f11c7f63SJim Harris *             a identify device command processed by the remote device.
565f11c7f63SJim Harris * @param[out] scsi_io This parameter specifies the user IO request for
566f11c7f63SJim Harris *             which to construct the ATA information page.
567f11c7f63SJim Harris *
568f11c7f63SJim Harris * @return none
569f11c7f63SJim Harris */
sati_inquiry_ata_information_translate_data(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * ata_input_data,void * scsi_io)570f11c7f63SJim Harris SATI_STATUS sati_inquiry_ata_information_translate_data(
571f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
572f11c7f63SJim Harris    void                       * ata_input_data,
573f11c7f63SJim Harris    void                       * scsi_io
574f11c7f63SJim Harris )
575f11c7f63SJim Harris {
576f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 0, 0x00);
577f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 1, SCSI_INQUIRY_ATA_INFORMATION_PAGE);
578f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 2, 0x02);
579f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 3, 0x38);
580f11c7f63SJim Harris 
581f11c7f63SJim Harris    //Reserved SAT2r07
582f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 4, 0x00);
583f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 5, 0x00);
584f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 6, 0x00);
585f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 7, 0x00);
586f11c7f63SJim Harris 
587f11c7f63SJim Harris    // The Vender identification field is set to "ATA     "
588f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 8, 0x41);
589f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 9, 0x54);
590f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 10, 0x41);
591f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 11, 0x20);
592f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 12, 0x20);
593f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 13, 0x20);
594f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 14, 0x20);
595f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 15, 0x20);
596f11c7f63SJim Harris 
597f11c7f63SJim Harris    //SAT Product identification
598f11c7f63SJim Harris    sati_ata_identify_device_copy_data(
599f11c7f63SJim Harris       sequence,
600f11c7f63SJim Harris       scsi_io,
601f11c7f63SJim Harris       16,
602f11c7f63SJim Harris       ata_input_data,
603f11c7f63SJim Harris       ATA_IDENTIFY_DEVICE_GET_OFFSET(model_number),
604f11c7f63SJim Harris       16,
605f11c7f63SJim Harris       TRUE
606f11c7f63SJim Harris    );
607f11c7f63SJim Harris 
608f11c7f63SJim Harris    //SAT Product Revision level bytes 32-35
609f11c7f63SJim Harris    sati_inquiry_construct_product_revision(
610f11c7f63SJim Harris       sequence,
611f11c7f63SJim Harris       ata_input_data,
612f11c7f63SJim Harris       scsi_io
613f11c7f63SJim Harris    );
614f11c7f63SJim Harris 
615f11c7f63SJim Harris    //skipping ATA device signature for now
616f11c7f63SJim Harris 
617f11c7f63SJim Harris    //Command code
618f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 56, 0xEC);
619f11c7f63SJim Harris 
620f11c7f63SJim Harris    //Reserved SAT2r07
621f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 57, 0x00);
622f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 58, 0x00);
623f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 59, 0x00);
624f11c7f63SJim Harris 
625f11c7f63SJim Harris    //copy all ATA identify device data
626f11c7f63SJim Harris    sati_ata_identify_device_copy_data(
627f11c7f63SJim Harris       sequence,
628f11c7f63SJim Harris       scsi_io,
629f11c7f63SJim Harris       60,
630f11c7f63SJim Harris       ata_input_data,
631f11c7f63SJim Harris       0,
632f11c7f63SJim Harris       sizeof(ATA_IDENTIFY_DEVICE_DATA_T),
633f11c7f63SJim Harris       FALSE
634f11c7f63SJim Harris    );
635f11c7f63SJim Harris 
636f11c7f63SJim Harris    //Need to send ATA Execute Device Diagnostic command still
637f11c7f63SJim Harris    sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE;
638f11c7f63SJim Harris 
639f11c7f63SJim Harris    return SATI_SEQUENCE_INCOMPLETE;
640f11c7f63SJim Harris }
641f11c7f63SJim Harris 
642f11c7f63SJim Harris /**
643f11c7f63SJim Harris  * @brief This method will translate the inquiry SCSI command into
644f11c7f63SJim Harris  *        an ATA IDENTIFY DEVICE command.  It will handle several different
645f11c7f63SJim Harris  *        VPD pages and the standard inquiry page.
646f11c7f63SJim Harris  *        For more information on the parameters passed to this method,
647f11c7f63SJim Harris  *        please reference sati_translate_command().
648f11c7f63SJim Harris  *
649f11c7f63SJim Harris  * @return Indicate if the command translation succeeded.
650f11c7f63SJim Harris  * @retval SCI_SUCCESS This is returned if the command translation was
651f11c7f63SJim Harris  *         successful.
652f11c7f63SJim Harris  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
653f11c7f63SJim Harris  *         the page isn't supported, or the page code
654f11c7f63SJim Harris  *         field is not zero when the EVPD bit is 0.
655f11c7f63SJim Harris  */
sati_inquiry_translate_command(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io)656f11c7f63SJim Harris SATI_STATUS sati_inquiry_translate_command(
657f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
658f11c7f63SJim Harris    void                       * scsi_io,
659f11c7f63SJim Harris    void                       * ata_io
660f11c7f63SJim Harris )
661f11c7f63SJim Harris {
662f11c7f63SJim Harris    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
663f11c7f63SJim Harris 
664f11c7f63SJim Harris    /**
665f11c7f63SJim Harris     * SPC dictates:
666f11c7f63SJim Harris     * - that the page code field must be 0, if VPD enable is 0.
667f11c7f63SJim Harris     */
668f11c7f63SJim Harris    if (  ((sati_get_cdb_byte(cdb, 1) & SCSI_INQUIRY_EVPD_ENABLE) == 0)
669f11c7f63SJim Harris       && (sati_get_cdb_byte(cdb, 2) != 0) )
670f11c7f63SJim Harris    {
671f11c7f63SJim Harris       sati_scsi_sense_data_construct(
672f11c7f63SJim Harris          sequence,
673f11c7f63SJim Harris          scsi_io,
674f11c7f63SJim Harris          SCSI_STATUS_CHECK_CONDITION,
675f11c7f63SJim Harris          SCSI_SENSE_ILLEGAL_REQUEST,
676f11c7f63SJim Harris          SCSI_ASC_INVALID_FIELD_IN_CDB,
677f11c7f63SJim Harris          SCSI_ASCQ_INVALID_FIELD_IN_CDB
678f11c7f63SJim Harris       );
679f11c7f63SJim Harris       return SATI_FAILURE_CHECK_RESPONSE_DATA;
680f11c7f63SJim Harris    }
681f11c7f63SJim Harris 
682f11c7f63SJim Harris    // Set the data length based on the allocation length field in the CDB.
683f11c7f63SJim Harris    sequence->allocation_length = (sati_get_cdb_byte(cdb, 3) << 8) |
684f11c7f63SJim Harris                                  (sati_get_cdb_byte(cdb, 4));
685f11c7f63SJim Harris 
686f11c7f63SJim Harris    // Check to see if there was a request for the vital product data or just
687f11c7f63SJim Harris    // the standard inquiry.
688f11c7f63SJim Harris    if (sati_get_cdb_byte(cdb, 1) & SCSI_INQUIRY_EVPD_ENABLE)
689f11c7f63SJim Harris    {
690f11c7f63SJim Harris       // Parse the page code to determine which translator to invoke.
691f11c7f63SJim Harris       switch (sati_get_cdb_byte(cdb, 2))
692f11c7f63SJim Harris       {
693f11c7f63SJim Harris          case SCSI_INQUIRY_SUPPORTED_PAGES_PAGE:
694f11c7f63SJim Harris             sequence->type  = SATI_SEQUENCE_INQUIRY_SUPPORTED_PAGES;
695f11c7f63SJim Harris             sati_inquiry_supported_pages_translate_data(sequence, scsi_io);
696f11c7f63SJim Harris             return SATI_COMPLETE;
697f11c7f63SJim Harris          break;
698f11c7f63SJim Harris 
699f11c7f63SJim Harris          case SCSI_INQUIRY_UNIT_SERIAL_NUM_PAGE:
700f11c7f63SJim Harris             sequence->type = SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER;
701f11c7f63SJim Harris          break;
702f11c7f63SJim Harris 
703f11c7f63SJim Harris          case SCSI_INQUIRY_DEVICE_ID_PAGE:
704f11c7f63SJim Harris             sequence->type = SATI_SEQUENCE_INQUIRY_DEVICE_ID;
705f11c7f63SJim Harris          break;
706f11c7f63SJim Harris 
707f11c7f63SJim Harris          case SCSI_INQUIRY_ATA_INFORMATION_PAGE:
708f11c7f63SJim Harris 
709f11c7f63SJim Harris             if(sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE)
710f11c7f63SJim Harris             {
711f11c7f63SJim Harris                sati_ata_execute_device_diagnostic_construct(
712f11c7f63SJim Harris                   ata_io,
713f11c7f63SJim Harris                   sequence
714f11c7f63SJim Harris                );
715f11c7f63SJim Harris                sequence->type = SATI_SEQUENCE_INQUIRY_EXECUTE_DEVICE_DIAG;
716f11c7f63SJim Harris             }
717f11c7f63SJim Harris             else
718f11c7f63SJim Harris             {
719f11c7f63SJim Harris                sequence->type = SATI_SEQUENCE_INQUIRY_ATA_INFORMATION;
720f11c7f63SJim Harris             }
721f11c7f63SJim Harris          break;
722f11c7f63SJim Harris 
723f11c7f63SJim Harris          case SCSI_INQUIRY_BLOCK_DEVICE_PAGE:
724f11c7f63SJim Harris             sequence->type = SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE;
725f11c7f63SJim Harris          break;
726f11c7f63SJim Harris 
727f11c7f63SJim Harris          default:
728f11c7f63SJim Harris             sati_scsi_sense_data_construct(
729f11c7f63SJim Harris                sequence,
730f11c7f63SJim Harris                scsi_io,
731f11c7f63SJim Harris                SCSI_STATUS_CHECK_CONDITION,
732f11c7f63SJim Harris                SCSI_SENSE_ILLEGAL_REQUEST,
733f11c7f63SJim Harris                SCSI_ASC_INVALID_FIELD_IN_CDB,
734f11c7f63SJim Harris                SCSI_ASCQ_INVALID_FIELD_IN_CDB
735f11c7f63SJim Harris             );
736f11c7f63SJim Harris             return SATI_FAILURE_CHECK_RESPONSE_DATA;
737f11c7f63SJim Harris          break;
738f11c7f63SJim Harris       }
739f11c7f63SJim Harris    }
740f11c7f63SJim Harris    else
741f11c7f63SJim Harris    {
742f11c7f63SJim Harris       sequence->type = SATI_SEQUENCE_INQUIRY_STANDARD;
743f11c7f63SJim Harris    }
744f11c7f63SJim Harris 
745f11c7f63SJim Harris    sati_ata_identify_device_construct(ata_io, sequence);
746f11c7f63SJim Harris 
747f11c7f63SJim Harris    return SATI_SUCCESS;
748f11c7f63SJim Harris }
749f11c7f63SJim Harris 
750f11c7f63SJim Harris /**
751f11c7f63SJim Harris * @brief This method finishes the construction of the SCSI data associated
752f11c7f63SJim Harris          with a request for the  ATA information vital product data (VPD) page.
753f11c7f63SJim Harris          The ATA device signature is written into the data response from the
754f11c7f63SJim Harris          task fle registers after issuing a Execute Device Diagnostic command.
755f11c7f63SJim Harris *
756f11c7f63SJim Harris * @param[in]  sequence This parameter specifies the translator sequence
757f11c7f63SJim Harris *             object to be utilized during data translation.
758f11c7f63SJim Harris * @param[out] scsi_io This parameter specifies the user IO request for
759f11c7f63SJim Harris *             which to construct the ATA information page.
760f11c7f63SJim Harris * @param[in]  ata_io This parameter specifies the ATA payload
761f11c7f63SJim Harris *             buffer location and size to be translated.
762f11c7f63SJim Harris *
763f11c7f63SJim Harris * @return none
764f11c7f63SJim Harris */
sati_inquiry_ata_information_finish_translation(SATI_TRANSLATOR_SEQUENCE_T * sequence,void * scsi_io,void * ata_io)765f11c7f63SJim Harris void sati_inquiry_ata_information_finish_translation(
766f11c7f63SJim Harris    SATI_TRANSLATOR_SEQUENCE_T * sequence,
767f11c7f63SJim Harris    void                       * scsi_io,
768f11c7f63SJim Harris    void                       * ata_io
769f11c7f63SJim Harris )
770f11c7f63SJim Harris {
771f11c7f63SJim Harris    U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
772f11c7f63SJim Harris    U32 offset;
773f11c7f63SJim Harris 
774f11c7f63SJim Harris    //SATA transport
775f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 36, 0x34);
776f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 37, 0x00);
777f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 38, (U8) sati_get_ata_status(register_fis));
778f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 39, (U8) sati_get_ata_error(register_fis));
779f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 40, sati_get_ata_lba_low(register_fis));
780f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 41, sati_get_ata_lba_mid(register_fis));
781f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 42, sati_get_ata_lba_high(register_fis));
782f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 43, sati_get_ata_device(register_fis));
783f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 44, sati_get_ata_lba_low_ext(register_fis));
784f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 45, sati_get_ata_lba_mid_ext(register_fis));
785f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 46, sati_get_ata_lba_high_ext(register_fis));
786f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 47, 0x00);
787f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 48, sati_get_ata_sector_count(register_fis));
788f11c7f63SJim Harris    sati_set_data_byte(sequence, scsi_io, 49, sati_get_ata_sector_count_exp(register_fis));
789f11c7f63SJim Harris 
790f11c7f63SJim Harris    for(offset = 50; offset < 56; offset++)
791f11c7f63SJim Harris    {
792f11c7f63SJim Harris       sati_set_data_byte(sequence, scsi_io, offset, 0x00);
793f11c7f63SJim Harris    }
794f11c7f63SJim Harris 
795f11c7f63SJim Harris    sequence->state = SATI_SEQUENCE_STATE_FINAL;
796f11c7f63SJim Harris }
797f11c7f63SJim Harris 
798f11c7f63SJim Harris #endif // !defined(DISABLE_SATI_INQUIRY)
799f11c7f63SJim Harris 
800