1230557Sjimharris/*-
2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license.  When using or
3230557Sjimharris * redistributing this file, you may do so under either license.
4230557Sjimharris *
5230557Sjimharris * GPL LICENSE SUMMARY
6230557Sjimharris *
7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8230557Sjimharris *
9230557Sjimharris * This program is free software; you can redistribute it and/or modify
10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as
11230557Sjimharris * published by the Free Software Foundation.
12230557Sjimharris *
13230557Sjimharris * This program is distributed in the hope that it will be useful, but
14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of
15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16230557Sjimharris * General Public License for more details.
17230557Sjimharris *
18230557Sjimharris * You should have received a copy of the GNU General Public License
19230557Sjimharris * along with this program; if not, write to the Free Software
20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21230557Sjimharris * The full GNU General Public License is included in this distribution
22230557Sjimharris * in the file called LICENSE.GPL.
23230557Sjimharris *
24230557Sjimharris * BSD LICENSE
25230557Sjimharris *
26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27230557Sjimharris * All rights reserved.
28230557Sjimharris *
29230557Sjimharris * Redistribution and use in source and binary forms, with or without
30230557Sjimharris * modification, are permitted provided that the following conditions
31230557Sjimharris * are met:
32230557Sjimharris *
33230557Sjimharris *   * Redistributions of source code must retain the above copyright
34230557Sjimharris *     notice, this list of conditions and the following disclaimer.
35230557Sjimharris *   * Redistributions in binary form must reproduce the above copyright
36230557Sjimharris *     notice, this list of conditions and the following disclaimer in
37230557Sjimharris *     the documentation and/or other materials provided with the
38230557Sjimharris *     distribution.
39230557Sjimharris *
40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51230557Sjimharris */
52230557Sjimharris
53230557Sjimharris#include <sys/cdefs.h>
54230557Sjimharris__FBSDID("$FreeBSD$");
55230557Sjimharris
56230557Sjimharris/**
57230557Sjimharris * @file
58230557Sjimharris * @brief This file contains the method implementations required to
59230557Sjimharris *        translate the SCSI mode sense 10-byte commands.
60230557Sjimharris */
61230557Sjimharris
62230557Sjimharris#if !defined(DISABLE_SATI_MODE_SENSE)
63230557Sjimharris
64230557Sjimharris#include <dev/isci/scil/sati_mode_sense.h>
65230557Sjimharris#include <dev/isci/scil/sati_mode_sense_10.h>
66230557Sjimharris#include <dev/isci/scil/sati_mode_pages.h>
67230557Sjimharris#include <dev/isci/scil/sati_callbacks.h>
68230557Sjimharris#include <dev/isci/scil/sati_util.h>
69230557Sjimharris#include <dev/isci/scil/intel_scsi.h>
70230557Sjimharris#include <dev/isci/scil/intel_ata.h>
71230557Sjimharris
72230557Sjimharris//******************************************************************************
73230557Sjimharris//* P R I V A T E   M E T H O D S
74230557Sjimharris//******************************************************************************
75230557Sjimharris
76230557Sjimharris/**
77230557Sjimharris * @brief This method builds the mode parameter header for a 10-byte SCSI
78230557Sjimharris *        mode sense data response.  The parameter header is 4 bytes in
79230557Sjimharris *        size.
80230557Sjimharris *        For more information on the parameters passed to this method,
81230557Sjimharris *        please reference sati_translate_command().
82230557Sjimharris *
83230557Sjimharris * @param[in] identify This parameter specifies the ATA remote device's
84230557Sjimharris *            received IDENTIFY DEVICE data.
85230557Sjimharris * @param[in] mode_data_length This parameter specifies the amount of data
86230557Sjimharris *            to be returned as part of this mode sense request.
87230557Sjimharris *
88230557Sjimharris * @return This method returns the number of bytes written into the
89230557Sjimharris *         mode sense data buffer.
90230557Sjimharris */
91230557Sjimharrisstatic
92230557SjimharrisU32 sati_mode_sense_10_build_header(
93230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
94230557Sjimharris   void                       * scsi_io,
95230557Sjimharris   ATA_IDENTIFY_DEVICE_DATA_T * identify,
96230557Sjimharris   U16                          mode_data_length
97230557Sjimharris)
98230557Sjimharris{
99230557Sjimharris   U8 * cdb = sati_cb_get_cdb_address(scsi_io);
100230557Sjimharris
101230557Sjimharris   // Fill in the length of the mode parameter data returned (do not include
102230557Sjimharris   // the size of the mode data length field in the total).  Adjust the
103230557Sjimharris   // mode data length to not include the mode data length fields itself
104230557Sjimharris   // (i.e. subtract 2).
105230557Sjimharris   mode_data_length -= 2;
106230557Sjimharris   sati_set_data_byte(sequence, scsi_io, 0, (U8)(mode_data_length >> 8) & 0xFF);
107230557Sjimharris   sati_set_data_byte(sequence, scsi_io, 1, (U8)(mode_data_length & 0xFF));
108230557Sjimharris
109230557Sjimharris   // Medium Type is 0 for SBC devices
110230557Sjimharris   sati_set_data_byte(sequence, scsi_io, 2, SCSI_MODE_HEADER_MEDIUM_TYPE_SBC);
111230557Sjimharris
112230557Sjimharris   // Write Protect (WP), Rsvd, DPOFUA, Rsvd
113230557Sjimharris   if (sequence->device->capabilities & SATI_DEVICE_CAP_DMA_FUA_ENABLE)
114230557Sjimharris      sati_set_data_byte(sequence,scsi_io,3,SCSI_MODE_SENSE_HEADER_FUA_ENABLE);
115230557Sjimharris   else
116230557Sjimharris      sati_set_data_byte(sequence, scsi_io, 3, 0);
117230557Sjimharris
118230557Sjimharris   // Set the reserved bytes to 0.  The LONGLBA field in byte 4 is overridden
119230557Sjimharris   // later in this method if LLBAA is enabled.
120230557Sjimharris   sati_set_data_byte(sequence, scsi_io, 4, 0);
121230557Sjimharris   sati_set_data_byte(sequence, scsi_io, 5, 0);
122230557Sjimharris
123230557Sjimharris   // The MSB for the block descriptor length is never used since the
124230557Sjimharris   // largest block descriptor in this translator is 16-bytes in size.
125230557Sjimharris   sati_set_data_byte(sequence, scsi_io, 6, 0);
126230557Sjimharris
127230557Sjimharris   // Set the LSB block descriptor length if block descriptors are utilized.
128230557Sjimharris   if (sati_get_cdb_byte(cdb, 1) & SCSI_MODE_SENSE_DBD_ENABLE)
129230557Sjimharris      sati_set_data_byte(sequence, scsi_io, 7, 0);
130230557Sjimharris   else
131230557Sjimharris   {
132230557Sjimharris      // If Long Logical Block Address are allowed, then the block descriptor
133230557Sjimharris      // is larger (16 bytes total).
134230557Sjimharris      if (sati_get_cdb_byte(cdb, 1) & SCSI_MODE_SENSE_LLBAA_ENABLE)
135230557Sjimharris      {
136230557Sjimharris         sati_set_data_byte(sequence, scsi_io, 4, 1);
137230557Sjimharris         sati_set_data_byte(
138230557Sjimharris            sequence, scsi_io, 7, SCSI_MODE_SENSE_LLBA_BLOCK_DESCRIPTOR_LENGTH
139230557Sjimharris         );
140230557Sjimharris      }
141230557Sjimharris      else
142230557Sjimharris      {
143230557Sjimharris         sati_set_data_byte(
144230557Sjimharris            sequence, scsi_io, 7, SCSI_MODE_SENSE_STD_BLOCK_DESCRIPTOR_LENGTH
145230557Sjimharris         );
146230557Sjimharris      }
147230557Sjimharris   }
148230557Sjimharris
149230557Sjimharris   return SCSI_MODE_SENSE_10_HEADER_LENGTH;
150230557Sjimharris}
151230557Sjimharris
152230557Sjimharrisstatic
153230557SjimharrisU32 sati_mode_sense_10_build_llba_block_descriptor(
154230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
155230557Sjimharris   void                       * scsi_io,
156230557Sjimharris   ATA_IDENTIFY_DEVICE_DATA_T * identify,
157230557Sjimharris   U32                          offset
158230557Sjimharris)
159230557Sjimharris{
160230557Sjimharris   U32  lba_low     = 0;
161230557Sjimharris   U32  lba_high    = 0;
162230557Sjimharris   U32  sector_size = 0;
163230557Sjimharris
164230557Sjimharris   // Extract the sector information (sector size, logical blocks) from
165230557Sjimharris   // the retrieved ATA identify device data.
166230557Sjimharris   sati_ata_identify_device_get_sector_info(
167230557Sjimharris      identify, &lba_low, &lba_high, &sector_size
168230557Sjimharris   );
169230557Sjimharris
170230557Sjimharris   // Fill in the 8-byte logical block area
171230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset,   (U8)((lba_high>>24) & 0xFF));
172230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset+1, (U8)((lba_high>>16) & 0xFF));
173230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset+2, (U8)((lba_high>>8)  & 0xFF));
174230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset+3, (U8)(lba_high & 0xFF));
175230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset+4, (U8)((lba_low>>24) & 0xFF));
176230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset+5, (U8)((lba_low>>16) & 0xFF));
177230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset+6, (U8)((lba_low>>8)  & 0xFF));
178230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset+7, (U8)(lba_low & 0xFF));
179230557Sjimharris
180230557Sjimharris   // Clear the reserved fields.
181230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset+8, 0);
182230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset+9, 0);
183230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset+10, 0);
184230557Sjimharris   sati_set_data_byte(sequence, scsi_io, offset+11, 0);
185230557Sjimharris
186230557Sjimharris   // Fill in the four byte Block Length field
187230557Sjimharris   sati_set_data_byte(sequence,scsi_io, offset+12, (U8)((sector_size>>24) & 0xFF));
188230557Sjimharris   sati_set_data_byte(sequence,scsi_io, offset+13, (U8)((sector_size>>16) & 0xFF));
189230557Sjimharris   sati_set_data_byte(sequence,scsi_io, offset+14, (U8)((sector_size>>8)  & 0xFF));
190230557Sjimharris   sati_set_data_byte(sequence,scsi_io, offset+15, (U8)(sector_size & 0xFF));
191230557Sjimharris
192230557Sjimharris   return SCSI_MODE_SENSE_LLBA_BLOCK_DESCRIPTOR_LENGTH;
193230557Sjimharris}
194230557Sjimharris
195230557Sjimharris/**
196230557Sjimharris * @brief This method perform the data translation common to all SCSI MODE
197230557Sjimharris *        SENSE 10 byte commands.  This includes building the mode page
198230557Sjimharris *        header and block descriptor (if requested).
199230557Sjimharris *        For more information on the parameters passed to this method,
200230557Sjimharris *        please reference sati_translate_command().
201230557Sjimharris *
202230557Sjimharris * @param[in] identify This parameter specifies the remote device's IDENTIFY
203230557Sjimharris *            DEVICE data to be used during translation.
204230557Sjimharris * @param[in] transfer_length This parameter specifies the size of the
205230557Sjimharris *            mode page (including header & block descriptor).
206230557Sjimharris *
207230557Sjimharris * @return This method returns the number of bytes written into the user's
208230557Sjimharris *         mode page data buffer.
209230557Sjimharris */
210230557Sjimharrisstatic
211230557SjimharrisU32 sati_mode_sense_10_translate_data(
212230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
213230557Sjimharris   ATA_IDENTIFY_DEVICE_DATA_T * identify,
214230557Sjimharris   void                       * scsi_io,
215230557Sjimharris   U16                          transfer_length
216230557Sjimharris)
217230557Sjimharris{
218230557Sjimharris   U8  * cdb = sati_cb_get_cdb_address(scsi_io);
219230557Sjimharris   U32   offset;
220230557Sjimharris
221230557Sjimharris   offset = sati_mode_sense_10_build_header(
222230557Sjimharris               sequence, scsi_io, identify, transfer_length
223230557Sjimharris            );
224230557Sjimharris
225230557Sjimharris   // Determine if the caller disabled block descriptors (DBD).  If not,
226230557Sjimharris   // then generate a block descriptor.
227230557Sjimharris   if ((sati_get_cdb_byte(cdb, 1) & SCSI_MODE_SENSE_DBD_ENABLE) == 0)
228230557Sjimharris   {
229230557Sjimharris      // If the user requested the Long LBA format descriptor, then build
230230557Sjimharris      // it
231230557Sjimharris      if (sati_get_cdb_byte(cdb, 1) & SCSI_MODE_SENSE_LLBAA_ENABLE)
232230557Sjimharris         offset += sati_mode_sense_10_build_llba_block_descriptor(
233230557Sjimharris                      sequence, scsi_io, identify, offset
234230557Sjimharris                   );
235230557Sjimharris      else
236230557Sjimharris         offset += sati_mode_sense_build_std_block_descriptor(
237230557Sjimharris                      sequence, scsi_io, identify, offset
238230557Sjimharris                   );
239230557Sjimharris   }
240230557Sjimharris
241230557Sjimharris   return offset;
242230557Sjimharris}
243230557Sjimharris
244230557Sjimharris//******************************************************************************
245230557Sjimharris//* P R O T E C T E D   M E T H O D S
246230557Sjimharris//******************************************************************************
247230557Sjimharris
248230557Sjimharris/**
249230557Sjimharris * @brief This method will translate the SCSI mode sense 6 byte command
250230557Sjimharris *        into corresponding ATA commands.  If the command is well-formed,
251230557Sjimharris *        then the translation will result in an ATA IDENTIFY DEVICE
252230557Sjimharris *        command.
253230557Sjimharris *        For more information on the parameters passed to this method,
254230557Sjimharris *        please reference sati_translate_command().
255230557Sjimharris *
256230557Sjimharris * @return Indicate if the command translation succeeded.
257230557Sjimharris * @retval SCI_SUCCESS This is returned if the command translation was
258230557Sjimharris *         successful.
259230557Sjimharris * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
260230557Sjimharris *         sense data has been created as a result of something specified
261230557Sjimharris *         in the CDB.
262230557Sjimharris */
263230557SjimharrisSATI_STATUS sati_mode_sense_10_translate_command(
264230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
265230557Sjimharris   void                       * scsi_io,
266230557Sjimharris   void                       * ata_io
267230557Sjimharris)
268230557Sjimharris{
269230557Sjimharris   U8 * cdb = sati_cb_get_cdb_address(scsi_io);
270230557Sjimharris
271230557Sjimharris   sequence->command_specific_data.scratch = 0;
272230557Sjimharris
273230557Sjimharris   // Set the data length based on the allocation length field in the CDB.
274230557Sjimharris   sequence->allocation_length = (sati_get_cdb_byte(cdb, 7) << 8) |
275230557Sjimharris                                 (sati_get_cdb_byte(cdb, 8));
276230557Sjimharris
277230557Sjimharris   return sati_mode_sense_translate_command(sequence, scsi_io, ata_io, 10);
278230557Sjimharris}
279230557Sjimharris
280230557Sjimharris/**
281230557Sjimharris * @brief This method will perform data translation from the supplied ATA
282230557Sjimharris *        input data (i.e. an ATA IDENTIFY DEVICE block) into a CACHING
283230557Sjimharris *        mode page format.  The data will be written into the user's mode
284230557Sjimharris *        page data buffer.  This function operates specifically for MODE
285230557Sjimharris *        SENSE 10 commands.
286230557Sjimharris *        For more information on the parameters passed to this method,
287230557Sjimharris *        please reference sati_translate_data().
288230557Sjimharris *
289230557Sjimharris * @return none.
290230557Sjimharris */
291230557Sjimharrisvoid sati_mode_sense_10_caching_translate_data(
292230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
293230557Sjimharris   void                       * ata_input_data,
294230557Sjimharris   void                       * scsi_io
295230557Sjimharris)
296230557Sjimharris{
297230557Sjimharris   ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
298230557Sjimharris                                           ata_input_data;
299230557Sjimharris   U16   data_length = sati_mode_sense_calculate_page_header(scsi_io, 10)
300230557Sjimharris                       + SCSI_MODE_PAGE_08_LENGTH;
301230557Sjimharris   U32   page_offset = sati_mode_sense_10_translate_data(
302230557Sjimharris                          sequence, identify, scsi_io, data_length
303230557Sjimharris                       );
304230557Sjimharris
305230557Sjimharris   sati_mode_sense_caching_translate_data(
306230557Sjimharris      sequence, scsi_io, identify, page_offset
307230557Sjimharris   );
308230557Sjimharris}
309230557Sjimharris
310230557Sjimharris/**
311230557Sjimharris * @brief This method will perform data translation from the supplied ATA
312230557Sjimharris *        input data (i.e. an ATA IDENTIFY DEVICE block) into a INFORMATIONAL
313230557Sjimharris *        EXCEPTIONS CONTROL mode page format.  The data will be written
314230557Sjimharris *        into the user's mode page data buffer.  This function operates
315230557Sjimharris *        specifically for MODE SENSE 10 commands.
316230557Sjimharris *        For more information on the parameters passed to this method,
317230557Sjimharris *        please reference sati_translate_data().
318230557Sjimharris *
319230557Sjimharris * @return none.
320230557Sjimharris */
321230557Sjimharrisvoid sati_mode_sense_10_informational_excp_control_translate_data(
322230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
323230557Sjimharris   void                       * ata_input_data,
324230557Sjimharris   void                       * scsi_io
325230557Sjimharris)
326230557Sjimharris{
327230557Sjimharris   ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
328230557Sjimharris                                           ata_input_data;
329230557Sjimharris   U16   data_length  = sati_mode_sense_calculate_page_header(scsi_io, 10)
330230557Sjimharris                        + SCSI_MODE_PAGE_1C_LENGTH;
331230557Sjimharris   U32   page_offset  = sati_mode_sense_10_translate_data(
332230557Sjimharris                           sequence, identify, scsi_io, data_length
333230557Sjimharris                        );
334230557Sjimharris
335230557Sjimharris   sati_mode_sense_informational_excp_control_translate_data(
336230557Sjimharris      sequence, scsi_io, identify, page_offset
337230557Sjimharris   );
338230557Sjimharris}
339230557Sjimharris
340230557Sjimharris/**
341230557Sjimharris* @brief This method will perform data translation from the supplied ATA
342230557Sjimharris*        input data (i.e. an ATA IDENTIFY DEVICE block) into a Read Write Error
343230557Sjimharris*         mode page format.  The data will be written
344230557Sjimharris*        into the user's mode page data buffer.  This function operates
345230557Sjimharris*        specifically for MODE SENSE 10 commands.
346230557Sjimharris*        For more information on the parameters passed to this method,
347230557Sjimharris*        please reference sati_translate_data().
348230557Sjimharris*
349230557Sjimharris* @return none.
350230557Sjimharris*/
351230557Sjimharrisvoid sati_mode_sense_10_read_write_error_translate_data(
352230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
353230557Sjimharris   void                       * ata_input_data,
354230557Sjimharris   void                       * scsi_io
355230557Sjimharris)
356230557Sjimharris{
357230557Sjimharris   ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
358230557Sjimharris      ata_input_data;
359230557Sjimharris
360230557Sjimharris   U16   data_length  = sati_mode_sense_calculate_page_header(scsi_io, 10)
361230557Sjimharris      + SCSI_MODE_PAGE_01_LENGTH;
362230557Sjimharris
363230557Sjimharris   U32   page_offset  = sati_mode_sense_10_translate_data(
364230557Sjimharris                           sequence, identify, scsi_io, data_length
365230557Sjimharris                        );
366230557Sjimharris
367230557Sjimharris   sati_mode_sense_read_write_error_translate_data(
368230557Sjimharris      sequence, scsi_io, identify, page_offset
369230557Sjimharris   );
370230557Sjimharris}
371230557Sjimharris
372230557Sjimharris/**
373230557Sjimharris* @brief This method will perform data translation from the supplied ATA
374230557Sjimharris*        input data (i.e. an ATA IDENTIFY DEVICE block) into a Disconnect
375230557Sjimharris*        Reconnect mode page format.  The data will be written
376230557Sjimharris*        into the user's mode page data buffer.  This function operates
377230557Sjimharris*        specifically for MODE SENSE 10 commands.
378230557Sjimharris*        For more information on the parameters passed to this method,
379230557Sjimharris*        please reference sati_translate_data().
380230557Sjimharris*
381230557Sjimharris* @return none.
382230557Sjimharris*/
383230557Sjimharrisvoid sati_mode_sense_10_disconnect_reconnect_translate_data(
384230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
385230557Sjimharris   void                       * ata_input_data,
386230557Sjimharris   void                       * scsi_io
387230557Sjimharris)
388230557Sjimharris{
389230557Sjimharris   ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
390230557Sjimharris      ata_input_data;
391230557Sjimharris
392230557Sjimharris   U8   data_length = (U8) sati_mode_sense_calculate_page_header(scsi_io, 10)
393230557Sjimharris      + SCSI_MODE_PAGE_02_LENGTH;
394230557Sjimharris
395230557Sjimharris   U32  page_offset = sati_mode_sense_10_translate_data(
396230557Sjimharris                        sequence, identify, scsi_io, data_length
397230557Sjimharris                      );
398230557Sjimharris
399230557Sjimharris   sati_mode_sense_disconnect_reconnect_translate_data(
400230557Sjimharris      sequence, scsi_io, identify, page_offset
401230557Sjimharris   );
402230557Sjimharris}
403230557Sjimharris
404230557Sjimharris/**
405230557Sjimharris* @brief This method will perform data translation from the supplied ATA
406230557Sjimharris*        input data (i.e. an ATA IDENTIFY DEVICE block) into a Control
407230557Sjimharris*         mode page format.  The data will be written
408230557Sjimharris*        into the user's mode page data buffer.  This function operates
409230557Sjimharris*        specifically for MODE SENSE 10 commands.
410230557Sjimharris*        For more information on the parameters passed to this method,
411230557Sjimharris*        please reference sati_translate_data().
412230557Sjimharris*
413230557Sjimharris* @return none.
414230557Sjimharris*/
415230557Sjimharrisvoid sati_mode_sense_10_control_translate_data(
416230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
417230557Sjimharris   void                       * ata_input_data,
418230557Sjimharris   void                       * scsi_io
419230557Sjimharris)
420230557Sjimharris{
421230557Sjimharris   ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
422230557Sjimharris      ata_input_data;
423230557Sjimharris
424230557Sjimharris   U8   data_length = (U8) sati_mode_sense_calculate_page_header(scsi_io, 10)
425230557Sjimharris      + SCSI_MODE_PAGE_0A_LENGTH;
426230557Sjimharris
427230557Sjimharris   U32  page_offset = sati_mode_sense_10_translate_data(
428230557Sjimharris                         sequence, identify, scsi_io, data_length
429230557Sjimharris                      );
430230557Sjimharris
431230557Sjimharris   sati_mode_sense_control_translate_data(
432230557Sjimharris      sequence, scsi_io, identify, page_offset
433230557Sjimharris   );
434230557Sjimharris}
435230557Sjimharris
436230557Sjimharris/**
437230557Sjimharris* @brief This method will perform data translation from the supplied ATA
438230557Sjimharris*        input data (i.e. an ATA IDENTIFY DEVICE block) into a Power
439230557Sjimharris*        Condition mode page format.  The data will be written
440230557Sjimharris*        into the user's mode page data buffer.  This function operates
441230557Sjimharris*        specifically for MODE SENSE 10 commands.
442230557Sjimharris*        For more information on the parameters passed to this method,
443230557Sjimharris*        please reference sati_translate_data().
444230557Sjimharris*
445230557Sjimharris* @return none.
446230557Sjimharris*/
447230557Sjimharrisvoid sati_mode_sense_10_power_condition_translate_data(
448230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
449230557Sjimharris   void                       * ata_input_data,
450230557Sjimharris   void                       * scsi_io
451230557Sjimharris)
452230557Sjimharris{
453230557Sjimharris   ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
454230557Sjimharris      ata_input_data;
455230557Sjimharris
456230557Sjimharris   U8 data_length;
457230557Sjimharris   U32  page_offset;
458230557Sjimharris
459230557Sjimharris   data_length = (U8) sati_mode_sense_calculate_page_header(scsi_io, 10)
460230557Sjimharris      + SCSI_MODE_PAGE_1A_LENGTH;
461230557Sjimharris
462230557Sjimharris   page_offset = sati_mode_sense_10_translate_data(
463230557Sjimharris      sequence, identify, scsi_io, data_length
464230557Sjimharris   );
465230557Sjimharris
466230557Sjimharris   sati_mode_sense_power_condition_translate_data(
467230557Sjimharris      sequence, scsi_io, identify, page_offset
468230557Sjimharris   );
469230557Sjimharris}
470230557Sjimharris
471230557Sjimharris
472230557Sjimharris/**
473230557Sjimharris * @brief This method will perform data translation from the supplied ATA
474230557Sjimharris *        input data (i.e. an ATA IDENTIFY DEVICE block) into an ALL
475230557Sjimharris *        PAGES mode page format.  The ALL PAGES mode page is basically a
476230557Sjimharris *        conglomeration of all mode pages and sub-pages into a single
477230557Sjimharris *        page.  The data will be written into the user's mode page
478230557Sjimharris *        data buffer.  This function operates specifically for MODE
479230557Sjimharris *        SENSE 10 commands.
480230557Sjimharris *        For more information on the parameters passed to this method,
481230557Sjimharris *        please reference sati_translate_data().
482230557Sjimharris *
483230557Sjimharris * @return none.
484230557Sjimharris */
485230557Sjimharrisvoid sati_mode_sense_10_all_pages_translate_data(
486230557Sjimharris   SATI_TRANSLATOR_SEQUENCE_T * sequence,
487230557Sjimharris   void                       * ata_input_data,
488230557Sjimharris   void                       * scsi_io
489230557Sjimharris)
490230557Sjimharris{
491230557Sjimharris   ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
492230557Sjimharris                                           ata_input_data;
493230557Sjimharris   U8   data_length = (U8) sati_mode_sense_calculate_page_header(scsi_io, 10)
494230557Sjimharris                           + SCSI_MODE_PAGE_01_LENGTH
495230557Sjimharris                           + SCSI_MODE_PAGE_02_LENGTH
496230557Sjimharris                           + SCSI_MODE_PAGE_08_LENGTH
497230557Sjimharris                           + SCSI_MODE_PAGE_0A_LENGTH
498230557Sjimharris                           + SCSI_MODE_PAGE_1C_LENGTH;
499230557Sjimharris   U32  page_offset = sati_mode_sense_10_translate_data(
500230557Sjimharris                         sequence, identify, scsi_io, data_length
501230557Sjimharris                      );
502230557Sjimharris
503230557Sjimharris   sati_mode_sense_all_pages_translate_data(
504230557Sjimharris      sequence, scsi_io, identify, page_offset
505230557Sjimharris   );
506230557Sjimharris}
507230557Sjimharris
508230557Sjimharris#endif // !defined(DISABLE_SATI_MODE_SENSE)
509230557Sjimharris
510