1/*-
2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3 *
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.
6 *
7 * GPL LICENSE SUMMARY
8 *
9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
10 *
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.
14 *
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.
19 *
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.
25 *
26 * BSD LICENSE
27 *
28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29 * All rights reserved.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 *
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
40 *     distribution.
41 *
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.
53 */
54
55#include <sys/cdefs.h>
56__FBSDID("$FreeBSD$");
57
58/**
59 * @file
60 * @brief This file contains the method implementations common to
61 *        translations that move data (i.e. read, write).  It has code for
62 *        the various different size CDBs (6, 10, 12, 16).
63 */
64
65#include <dev/isci/scil/sati_move.h>
66#include <dev/isci/scil/sati_callbacks.h>
67#include <dev/isci/scil/sati_translator_sequence.h>
68#include <dev/isci/scil/sati_util.h>
69#include <dev/isci/scil/intel_ata.h>
70#include <dev/isci/scil/intel_scsi.h>
71#include <dev/isci/scil/intel_sat.h>
72
73//******************************************************************************
74//* P R I V A T E   M E T H O D S
75//******************************************************************************
76
77/**
78 * @brief This method simply sets the command register based upon the
79 *        supplied opcodes and the data direction.
80 *        For more information on the parameters passed to this method,
81 *        please reference sati_translate_command()
82 *
83 * @param[in] write_opcode This parameter specifies the value to be written
84 *            to the ATA command register for a write (data out) operation.
85 * @param[in] read_opcode This parameter specifies the value to be written
86 *            to the ATA command register for a read (data in) operation.
87 *
88 * @return none.
89 */
90static
91void sati_move_set_ata_command(
92   SATI_TRANSLATOR_SEQUENCE_T * sequence,
93   void                       * ata_io,
94   U8                           write_opcode,
95   U8                           read_opcode
96)
97{
98   U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
99
100   if (sequence->data_direction == SATI_DATA_DIRECTION_OUT)
101      sati_set_ata_command(register_fis, write_opcode);
102   else
103      sati_set_ata_command(register_fis, read_opcode);
104}
105
106/**
107 * @brief This method will translate the SCSI transfer count from the 6-byte
108 *        CDB into the appropriate amount in the ATA register FIS.  Please
109 *        note for 48-bit UDMA requests, the caller must set the sector
110 *        count extended field.  This method also sets protocol and
111 *        command fields.
112 *        For more information on the parameters passed to this method,
113 *        please reference sati_translate_command()
114 *
115 * @param[in] write_opcode This parameter specifies the value to be written
116 *            to the ATA command register for a write (data out) operation.
117 * @param[in] read_opcode This parameter specifies the value to be written
118 *            to the ATA command register for a read (data in) operation.
119 *
120 * @return none
121 */
122static
123void sati_move_small_udma_translate_command(
124   SATI_TRANSLATOR_SEQUENCE_T * sequence,
125   void                       * scsi_io,
126   void                       * ata_io,
127   U8                           write_opcode,
128   U8                           read_opcode
129)
130{
131   U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
132   U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
133
134   sati_move_set_ata_command(sequence, ata_io, write_opcode, read_opcode);
135   sati_set_ata_sector_count(register_fis, sati_get_cdb_byte(cdb, 4));
136
137   if (sequence->data_direction == SATI_DATA_DIRECTION_IN)
138      sequence->protocol = SAT_PROTOCOL_UDMA_DATA_IN;
139   else
140      sequence->protocol = SAT_PROTOCOL_UDMA_DATA_OUT;
141}
142
143/**
144 * @brief This method will translate the SCSI transfer count from the
145 *        supplied sector_count parameter into the ATA register FIS.
146 *        The translation is specific to 10,12, 16 byte CDBs.
147 *        This method also sets protocol and command fields.
148 *        For more information on the parameters passed to this method,
149 *        please reference sati_translate_command()
150 *
151 * @param[in] sector_count This parameter specifies the number of sectors
152 *            to be transferred.
153 * @param[in] write_opcode This parameter specifies the value to be written
154 *            to the ATA command register for a write (data out) operation.
155 * @param[in] read_opcode This parameter specifies the value to be written
156 *            to the ATA command register for a read (data in) operation.
157 *
158 * @return Please reference sati_move_set_sector_count() for information
159 *         on return codes from this method.
160 */
161static
162SATI_STATUS sati_move_large_udma_translate_command(
163   SATI_TRANSLATOR_SEQUENCE_T * sequence,
164   void                       * scsi_io,
165   void                       * ata_io,
166   U32                          sector_count,
167   U8                           write_opcode,
168   U8                           read_opcode
169)
170{
171   sati_move_set_ata_command(sequence, ata_io, write_opcode, read_opcode);
172
173   if (sequence->data_direction == SATI_DATA_DIRECTION_IN)
174      sequence->protocol = SAT_PROTOCOL_UDMA_DATA_IN;
175   else
176      sequence->protocol = SAT_PROTOCOL_UDMA_DATA_OUT;
177
178   return sati_move_set_sector_count(
179             sequence, scsi_io, ata_io, sector_count, FALSE
180          );
181}
182
183/**
184 * @brief This method will translate the SCSI transfer count from the 6-byte
185 *        CDB into the appropriate amount in the ATA register FIS.
186 *        This is only used for translation of 6-byte SCSI CDBs.
187 *        For more information on the parameters passed to this method,
188 *        please reference sati_translate_command()
189 *
190 * @return none
191 */
192static
193void sati_move_ncq_translate_8_bit_sector_count(
194   void * scsi_io,
195   void * ata_io
196)
197{
198   U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
199   U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
200
201   sati_set_ata_features(register_fis, sati_get_cdb_byte(cdb, 4));
202
203   // A read 6 with a 0 sector count indicates a transfer of 256 sectors.
204   // As a result update the MSB (features expanded register) to indicate
205   // 256 sectors (0x100).
206   if (sati_get_cdb_byte(cdb, 4) == 0)
207      sati_set_ata_features_exp(register_fis, 1);
208}
209
210//******************************************************************************
211//* P U B L I C   M E T H O D S
212//******************************************************************************
213
214/**
215 * @brief This method will process a 32-bit sector into the appropriate fields
216 *        in a register FIS.  This method works for both 8-bit and 16-bit sector
217 *        counts.
218 *        This is used for translation of 10, 12, and 16-byte SCSI CDBs.
219 *        For more information on the parameters passed to this method,
220 *        please reference sati_translate_command().
221 *
222 * @note This method should only be called for CDB sizes of 10-bytes or larger.
223 *
224 * @param[in] sector_count This parameter specifies the number of sectors
225 *            to be transferred.
226 * @param[in] is_fpdma_command This parameter indicates if the supplied
227 *            ata_io is a first party DMA request (NCQ).
228 *
229 * @return none
230 */
231SATI_STATUS sati_move_set_sector_count(
232   SATI_TRANSLATOR_SEQUENCE_T * sequence,
233   void                       * scsi_io,
234   void                       * ata_io,
235   U32                          sector_count,
236   U8                           is_fpdma_command
237)
238{
239   U32  max_sector_count;
240   U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
241
242   if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE)
243      max_sector_count = 65536;
244   else
245      max_sector_count = 256;
246
247   // Check the CDB transfer length count and set the register FIS sector
248   // count fields
249   if (0 == sector_count)
250   {
251      // A SCSI sector count of 0 for 10-byte CDBs and larger indicate no data
252      // transfer, so simply complete the command immediately.
253      return SATI_COMPLETE;
254   }
255   else if (sector_count >= max_sector_count)
256   {
257      // We have to perform multiple SATA commands to satisfy the sector
258      // count specified in the SCSI command.
259      sequence->command_specific_data.move_sector_count =
260         sector_count - max_sector_count;
261
262      // In ATA a sector count of 0 indicates use the maximum allowed for
263      // the command (i.e. 0 == 2^16 or 2^8).
264      sector_count = 0;
265   }
266
267   if (is_fpdma_command)
268   {
269      sati_set_ata_features(register_fis, sector_count & 0xFF);
270      sati_set_ata_features_exp(register_fis, (sector_count >> 8) & 0xFF);
271   }
272   else
273   {
274      sati_set_ata_sector_count(register_fis, sector_count & 0xFF);
275      sati_set_ata_sector_count_exp(register_fis, (sector_count >> 8) & 0xFF);
276   }
277
278   return SATI_SUCCESS;
279}
280
281/**
282 * @brief This method simply translates the 32-bit logical block address
283 *        field from the SCSI CDB (10 or 12-byte) into the ATA task
284 *        file (register FIS).
285 *        For more information on the parameters passed to this method,
286 *        please reference sati_translate_command()
287 *
288 * @return none
289 */
290void sati_move_translate_32_bit_lba(
291   SATI_TRANSLATOR_SEQUENCE_T * sequence,
292   void                       * scsi_io,
293   void                       * ata_io
294)
295{
296   U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
297   U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
298
299   sati_set_ata_lba_low(register_fis, sati_get_cdb_byte(cdb, 5));
300   sati_set_ata_lba_mid(register_fis, sati_get_cdb_byte(cdb, 4));
301   sati_set_ata_lba_high(register_fis, sati_get_cdb_byte(cdb, 3));
302   sati_set_ata_lba_low_exp(register_fis, sati_get_cdb_byte(cdb, 2));
303   sati_set_ata_lba_mid_exp(register_fis, 0);
304   sati_set_ata_lba_high_exp(register_fis, 0);
305}
306
307/**
308 * @brief This method simply translates the 64-bit logical block address
309 *        field from the SCSI CDB (16 byte) into the ATA task
310 *        file (register FIS).  The 2 most significant bytes must be 0,
311 *        since ATA devices can, at most, support 48-bits of LBA.
312 *        For more information on the parameters passed to this method,
313 *        please reference sati_translate_command()
314 *
315 * @return Indicate if the LBA translation succeeded.
316 * @return SATI_SUCCESS This is returned if translation was successful.
317 * @return SATI_FAILURE_CHECK_RESPONSE_DATA This is returned if either
318 *         of the 2 most significant bytes contain a non-zero value.
319 */
320SATI_STATUS sati_move_translate_64_bit_lba(
321   SATI_TRANSLATOR_SEQUENCE_T * sequence,
322   void                       * scsi_io,
323   void                       * ata_io
324)
325{
326   U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
327   U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
328
329   // Ensure we receive a logical block address that is within range of
330   // addressibility per the ATA specification (i.e. 48-bit or 28-bit).
331   if ( (sati_get_cdb_byte(cdb, 2) == 0) && (sati_get_cdb_byte(cdb, 3) == 0) )
332   {
333      sati_set_ata_lba_low(register_fis, sati_get_cdb_byte(cdb, 9));
334      sati_set_ata_lba_mid(register_fis, sati_get_cdb_byte(cdb, 8));
335      sati_set_ata_lba_high(register_fis, sati_get_cdb_byte(cdb, 7));
336      sati_set_ata_lba_low_exp(register_fis, sati_get_cdb_byte(cdb, 6));
337      sati_set_ata_lba_mid_exp(register_fis, sati_get_cdb_byte(cdb, 5));
338      sati_set_ata_lba_high_exp(register_fis, sati_get_cdb_byte(cdb, 4));
339      return SATI_SUCCESS;
340   }
341   else
342   {
343      sati_scsi_sense_data_construct(
344         sequence,
345         scsi_io,
346         SCSI_STATUS_CHECK_CONDITION,
347         SCSI_SENSE_ILLEGAL_REQUEST,
348         SCSI_ASC_LBA_OUT_OF_RANGE,
349         SCSI_ASCQ_LBA_OUT_OF_RANGE
350      );
351      return SATI_FAILURE_CHECK_RESPONSE_DATA;
352   }
353}
354
355/**
356 * @brief This method will translate the pieces common to SCSI read and
357 *        write 6 byte commands.  Depending upon the capabilities
358 *        supported by the target different ATA commands can be selected.
359 *        For more information on the parameters passed to this method,
360 *        please reference sati_translate_command().
361 *
362 * @return Indicate if the command translation succeeded.
363 * @retval SCI_SUCCESS This is returned if the command translation was
364 *         successful.
365 */
366SATI_STATUS sati_move_6_translate_command(
367   SATI_TRANSLATOR_SEQUENCE_T * sequence,
368   void                       * scsi_io,
369   void                       * ata_io
370)
371{
372   U8 * cdb          = sati_cb_get_cdb_address(scsi_io);
373   U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
374
375   // Translate the logical block address information from the SCSI CDB.
376   // There is only 5 bits of MSB located in byte 1 of the CDB.
377   sati_set_ata_lba_low(register_fis, sati_get_cdb_byte(cdb, 3));
378   sati_set_ata_lba_mid(register_fis, sati_get_cdb_byte(cdb, 2));
379   sati_set_ata_lba_high(register_fis, sati_get_cdb_byte(cdb, 1) & 0x1F);
380
381   sati_move_translate_command(sequence, scsi_io, ata_io, 0);
382
383   return SATI_SUCCESS;
384}
385
386/**
387 * @brief This method will translate the pieces common to SCSI read and
388 *        write 10/12 byte commands.  Depending upon the capabilities
389 *        supported by the target different ATA commands can be selected.
390 *        For more information on the parameters passed to this method,
391 *        please reference sati_translate_command().
392 *
393 * @param[in] device_head This parameter specifies the contents to be
394 *            written to the device head register.
395 *
396 * @return Indicate if the command translation succeeded.
397 * @retval SCI_SUCCESS This is returned if the command translation was
398 *         successful.
399 */
400SATI_STATUS sati_move_32_bit_lba_translate_command(
401   SATI_TRANSLATOR_SEQUENCE_T * sequence,
402   void                       * scsi_io,
403   void                       * ata_io,
404   U8                           device_head
405)
406{
407   sati_move_translate_32_bit_lba(sequence, scsi_io, ata_io);
408   sati_move_translate_command(sequence, scsi_io, ata_io, device_head);
409
410   return SATI_SUCCESS;
411}
412
413/**
414 * @brief This method provides the common translation functionality for
415 *        the 6-byte move command descriptor blocks (CDBs).
416 *        This method will ensure that the following is performed:
417 *        - command register is set
418 *        - the SATI_TRANSLATOR_SEQUENCE::protocol field is set
419 *        - the sector count field(s) are set
420 *        - sati_move_6_translate_command() is invoked.
421 *        For more information on the parameters passed to this method,
422 *        please reference sati_translate_command().
423 *
424 * @pre The caller must ensure that the
425 *      SATI_TRANSLATOR_SEQUENCE::data_direction field has already been set.
426 *
427 * @return Indicate if the command translation succeeded.
428 * @see sati_move_6_translate_command() for additional return codes.
429 */
430SATI_STATUS sati_move_small_translate_command(
431   SATI_TRANSLATOR_SEQUENCE_T * sequence,
432   void                       * scsi_io,
433   void                       * ata_io
434)
435{
436   // Translation of the sector count is performed differently for NCQ vs.
437   // other protocols.
438   if (sequence->device->capabilities & SATI_DEVICE_CAP_NCQ_SUPPORTED_ENABLE)
439   {
440      sati_move_set_ata_command(
441         sequence, ata_io, ATA_WRITE_FPDMA, ATA_READ_FPDMA
442      );
443      sati_move_ncq_translate_8_bit_sector_count(scsi_io, ata_io);
444      sequence->protocol = SAT_PROTOCOL_FPDMA;
445   }
446   else if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE)
447   {
448      U8 * cdb = sati_cb_get_cdb_address(scsi_io);
449
450      sati_move_small_udma_translate_command(
451         sequence, scsi_io, ata_io, ATA_WRITE_DMA_EXT, ATA_READ_DMA_EXT
452      );
453
454      // A read/write 6 with a 0 sector count indicates a transfer of 256
455      // sectors.  As a result update the MSB (features expanded register)
456      // to indicate 256 sectors (0x100).
457      if (sati_get_cdb_byte(cdb, 4) == 0)
458      {
459         U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
460         sati_set_ata_sector_count_exp(register_fis, 1);
461      }
462   }
463   else if (sequence->device->capabilities & SATI_DEVICE_CAP_UDMA_ENABLE)
464   {
465      sati_move_small_udma_translate_command(
466         sequence, scsi_io, ata_io, ATA_WRITE_DMA, ATA_READ_DMA
467      );
468   }
469   else
470   {
471      /**
472       * Currently the translation does not support devices incapable of
473       * handling the 48-bit feature set (i.e. 16 bits of sector count).
474       */
475      sati_scsi_sense_data_construct(
476         sequence,
477         scsi_io,
478         SCSI_STATUS_CHECK_CONDITION,
479         SCSI_SENSE_ILLEGAL_REQUEST,
480         SCSI_ASC_INVALID_FIELD_IN_CDB,
481         SCSI_ASCQ_INVALID_FIELD_IN_CDB
482      );
483      return SATI_FAILURE_CHECK_RESPONSE_DATA;
484   }
485
486   return sati_move_6_translate_command(sequence, scsi_io, ata_io);
487}
488
489/**
490 * @brief This method provides the common translation functionality for
491 *        the larger command descriptor blocks (10, 12, 16-byte CDBs).
492 *        For more information on the parameters passed to this method,
493 *        please reference sati_translate_command().
494 *
495 * @param[in] sector_count This parameter specifies the number of sectors
496 *            to be transferred.
497 * @param[in] device_head This parameter specifies the contents to be
498 *            written to the device head register.
499 *
500 * @return Indicate if the command translation succeeded.
501 * @retval SATI_FAILURE This value is returned if neither NCQ or DMA is
502 *         supported by the target device.
503 * @see sati_move_set_sector_count() for additional return codes.
504 */
505SATI_STATUS sati_move_large_translate_command(
506   SATI_TRANSLATOR_SEQUENCE_T * sequence,
507   void                       * scsi_io,
508   void                       * ata_io,
509   U32                          sector_count,
510   U8                         * ata_device_head
511)
512{
513   SATI_STATUS   status = SATI_SUCCESS;
514   U8          * cdb    = sati_cb_get_cdb_address(scsi_io);
515
516   // Parts of translation (e.g. sector count) is performed differently
517   // for NCQ vs. other protocols.
518   if (sequence->device->capabilities & SATI_DEVICE_CAP_NCQ_SUPPORTED_ENABLE)
519   {
520      // if the user did not request to ignore FUA
521      if((sequence->device->capabilities & SATI_DEVICE_CAP_IGNORE_FUA)==0)
522      {
523         // Is the Force Unit Access bit set?
524         if (sati_get_cdb_byte(cdb, 1) & SCSI_MOVE_FUA_BIT_ENABLE)
525            *ata_device_head = ATA_DEV_HEAD_REG_FUA_ENABLE;
526      }
527
528      sati_move_set_ata_command(
529         sequence, ata_io, ATA_WRITE_FPDMA, ATA_READ_FPDMA
530      );
531      status = sati_move_set_sector_count(
532                  sequence, scsi_io, ata_io, sector_count, TRUE
533               );
534      sequence->protocol = SAT_PROTOCOL_FPDMA;
535   }
536   else if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE)
537   {
538      // Is the Force Unit Access bit set?  If it is, then error.  We
539      // aren't supporting this yet for normal DMA.
540      if (sati_get_cdb_byte(cdb, 1) & SCSI_MOVE_FUA_BIT_ENABLE)
541      {
542         sati_scsi_sense_data_construct(
543            sequence,
544            scsi_io,
545            SCSI_STATUS_CHECK_CONDITION,
546            SCSI_SENSE_ILLEGAL_REQUEST,
547            SCSI_ASC_INVALID_FIELD_IN_CDB,
548            SCSI_ASCQ_INVALID_FIELD_IN_CDB
549         );
550         return SATI_FAILURE_CHECK_RESPONSE_DATA;
551      }
552
553      status = sati_move_large_udma_translate_command(
554                  sequence,
555                  scsi_io,
556                  ata_io,
557                  sector_count,
558                  ATA_WRITE_DMA_EXT,
559                  ATA_READ_DMA_EXT
560               );
561   }
562   else if (sequence->device->capabilities & SATI_DEVICE_CAP_UDMA_ENABLE)
563   {
564      status = sati_move_large_udma_translate_command(
565                  sequence,
566                  scsi_io,
567                  ata_io,
568                  sector_count,
569                  ATA_WRITE_DMA,
570                  ATA_READ_DMA
571               );
572   }
573   else
574   {
575      /**
576       * Currently the translation does not support devices incapable of
577       * handling the 48-bit feature set (i.e. 16 bits of sector count).
578       */
579      sati_scsi_sense_data_construct(
580         sequence,
581         scsi_io,
582         SCSI_STATUS_CHECK_CONDITION,
583         SCSI_SENSE_ILLEGAL_REQUEST,
584         SCSI_ASC_INVALID_FIELD_IN_CDB,
585         SCSI_ASCQ_INVALID_FIELD_IN_CDB
586      );
587      return SATI_FAILURE_CHECK_RESPONSE_DATA;
588   }
589
590   return status;
591}
592
593/**
594 * @brief This method simply performs the functionality common to all
595 *        payload data movement translations (i.e. READ/WRITE).
596 *        For more information on the parameters passed to this method,
597 *        please reference sati_translate_command().
598 *
599 * @param[in] device_head This parameter specifies the current contents
600 *            to be written to the ATA task file (register FIS) device
601 *            head register.
602 *
603 * @return none
604 */
605void sati_move_translate_command(
606   SATI_TRANSLATOR_SEQUENCE_T * sequence,
607   void                       * scsi_io,
608   void                       * ata_io,
609   U8                           device_head
610)
611{
612   U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
613
614   sati_set_ata_device_head(
615      register_fis, device_head | ATA_DEV_HEAD_REG_LBA_MODE_ENABLE
616   );
617}
618
619