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