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 all of the method implementations that 61 * provide generic support for SATI. Some methods can be utilized 62 * by a user to construct ATA/ATAPI commands, copy ATA device 63 * structure data, fill in sense data, etc. 64 */ 65 66 #include <dev/isci/scil/sati_util.h> 67 #include <dev/isci/scil/sati_callbacks.h> 68 #include <dev/isci/scil/intel_scsi.h> 69 #include <dev/isci/scil/intel_ata.h> 70 #include <dev/isci/scil/intel_sat.h> 71 #include <dev/isci/scil/intel_sas.h> 72 73 /** 74 * @brief This method will set the data direction, protocol, and transfer 75 * kength for an ATA non-data command. 76 * 77 * @pre It is expected that the user will use this method for setting these 78 * values in a non-data ATA command constuct. 79 * 80 * @param[out] ata_io This parameter specifies the ATA IO request structure 81 * for which to build the IDENTIFY DEVICE command. 82 * @param[in] sequence This parameter specifies the translator sequence 83 * for which the command is being constructed. 84 * 85 * @return none. 86 */ 87 void sati_ata_non_data_command( 88 void * ata_io, 89 SATI_TRANSLATOR_SEQUENCE_T * sequence 90 ) 91 { 92 sequence->data_direction = SATI_DATA_DIRECTION_NONE; 93 sequence->protocol = SAT_PROTOCOL_NON_DATA; 94 sequence->ata_transfer_length = 0; 95 } 96 97 /** 98 * @brief This method will construct the ATA identify device command. 99 * 100 * @pre It is expected that the user has properly set the current contents 101 * of the register FIS to 0. 102 * 103 * @param[out] ata_io This parameter specifies the ATA IO request structure 104 * for which to build the IDENTIFY DEVICE command. 105 * @param[in] sequence This parameter specifies the translator sequence 106 * for which the command is being constructed. 107 * 108 * @return none. 109 */ 110 void sati_ata_identify_device_construct( 111 void * ata_io, 112 SATI_TRANSLATOR_SEQUENCE_T * sequence 113 ) 114 { 115 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 116 117 sati_set_ata_command(register_fis, ATA_IDENTIFY_DEVICE); 118 sequence->data_direction = SATI_DATA_DIRECTION_IN; 119 sequence->protocol = SAT_PROTOCOL_PIO_DATA_IN; 120 sequence->ata_transfer_length = sizeof(ATA_IDENTIFY_DEVICE_DATA_T); 121 } 122 123 /** 124 * @brief This method will construct the ATA Execute Device Diagnostic command. 125 * 126 * @param[out] ata_io This parameter specifies the ATA IO request structure 127 * for which to build the IDENTIFY DEVICE command. 128 * @param[in] sequence This parameter specifies the translator sequence 129 * for which the command is being constructed. 130 * 131 * @return none. 132 */ 133 void sati_ata_execute_device_diagnostic_construct( 134 void * ata_io, 135 SATI_TRANSLATOR_SEQUENCE_T * sequence 136 ) 137 { 138 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 139 140 sati_set_ata_command(register_fis, ATA_EXECUTE_DEVICE_DIAG); 141 142 sequence->data_direction = SATI_DATA_DIRECTION_IN; 143 sequence->protocol = SAT_PROTOCOL_DEVICE_DIAGNOSTIC; 144 sequence->ata_transfer_length = 16; 145 } 146 147 /** 148 * @brief This method will set data bytes in the user data area. If the 149 * caller requests it, the data written will be forced to ascii 150 * printable characters if it isn't already a printable character. 151 * A printable character is considered to be >= 0x20 and <= 0x70. 152 * 153 * @param[in] sequence This parameter specifies the translation sequence 154 * for which to copy and swap the data. 155 * @param[out] destination_scsi_io This parameter specifies the SCSI IO 156 * request containing the destination buffer into which to copy. 157 * @param[in] destination_offset This parameter specifies the offset into 158 * the data buffer where the information will be copied to. 159 * @param[in] source_value This parameter specifies the value retrieved 160 * from the source buffer that is to be copied into the user 161 * buffer area. 162 * @param[in] use_printable_chars This parameter indicates if the copy should 163 * ensure that the value copied is considered an ASCII printable 164 * character (e.g. A, B, " ", etc.). These characters reside 165 * in the 0x20 - 0x7E ASCII range. 166 * 167 * @return none 168 */ 169 static 170 void sati_set_ascii_data_byte( 171 SATI_TRANSLATOR_SEQUENCE_T * sequence, 172 void * destination_scsi_io, 173 U32 destination_offset, 174 U8 source_value, 175 BOOL use_printable_chars 176 ) 177 { 178 // if the user requests that the copied data be ascii printable, then 179 // default to " " (i.e. 0x20) for all non-ascii printable characters. 180 if((use_printable_chars == TRUE) 181 && ((source_value < 0x20) || (source_value > 0x7E))) 182 { 183 source_value = 0x20; 184 } 185 186 sati_set_data_byte( 187 sequence, destination_scsi_io, destination_offset, source_value 188 ); 189 } 190 191 /** 192 * @brief This method performs a copy operation using an offset into the 193 * source buffer, an offset into the destination buffer, and a length. 194 * It will perform the byte swap from the 16-bit identify field 195 * into the network byte order SCSI location. 196 * 197 * @param[in] sequence This parameter specifies the translation sequence 198 * for which to copy and swap the data. 199 * @param[out] destination_scsi_io This parameter specifies the SCSI IO 200 * request containing the destination buffer into which to copy. 201 * @param[in] destination_offset This parameter specifies the offset into 202 * the data buffer where the information will be copied to. 203 * @param[in] source_buffer This parameter specifies the source buffer from 204 * which the data will be copied. 205 * @param[in] source_offset This parameter specifies the offset into the 206 * source buffer where the copy shall begin. 207 * @param[in] length This parameter specifies the number of bytes to copy 208 * during this operation. 209 * @param[in] use_printable_chars This parameter indicates if the copy should 210 * ensure that the value copied is considered an ASCII printable 211 * character (e.g. A, B, " ", etc.). These characters reside 212 * in the 0x20 - 0x7E ASCII range. 213 * 214 * @return none 215 */ 216 void sati_ata_identify_device_copy_data( 217 SATI_TRANSLATOR_SEQUENCE_T * sequence, 218 void * destination_scsi_io, 219 U32 destination_offset, 220 U8 * source_buffer, 221 U32 source_offset, 222 U32 length, 223 BOOL use_printable_chars 224 ) 225 { 226 source_buffer += source_offset; 227 while (length > 0) 228 { 229 sati_set_ascii_data_byte( 230 sequence, 231 destination_scsi_io, 232 destination_offset, 233 *(source_buffer+1), 234 use_printable_chars 235 ); 236 237 sati_set_ascii_data_byte( 238 sequence, 239 destination_scsi_io, 240 destination_offset+1, 241 *source_buffer, 242 use_printable_chars 243 ); 244 245 destination_offset += 2; 246 source_buffer += 2; 247 length -= 2; 248 } 249 } 250 251 /** 252 * @brief This method performs a copy operation using a source buffer, 253 * an offset into the destination buffer, and a length. 254 * 255 * @param[in] sequence This parameter specifies the translation sequence 256 * for which to copy and swap the data. 257 * @param[out] destination_scsi_io This parameter specifies the SCSI IO 258 * request containing the destination buffer into which to copy. 259 * @param[in] destination_offset This parameter specifies the offset into 260 * the data buffer where the information will be copied to. 261 * @param[in] source_buffer This parameter specifies the source buffer from 262 * which the data will be copied. 263 * @param[in] length This parameter specifies the number of bytes to copy 264 * during this operation. 265 * 266 * @return none 267 */ 268 void sati_copy_data( 269 SATI_TRANSLATOR_SEQUENCE_T * sequence, 270 void * destination_scsi_io, 271 U32 destination_offset, 272 U8 * source_buffer, 273 U32 length 274 ) 275 { 276 while (length > 0) 277 { 278 sati_set_data_byte( 279 sequence, destination_scsi_io, destination_offset, *source_buffer 280 ); 281 282 destination_offset++; 283 source_buffer++; 284 length--; 285 } 286 } 287 288 /** 289 * @brief This method extracts the Logical Block Address high and low 32-bit 290 * values and the sector count 32-bit value from the ATA identify 291 * device data. 292 * 293 * @param[in] identify This parameter specifies the ATA_IDENTIFY_DEVICE_DATA 294 * from which to extract the sector information. 295 * @param[out] lba_high This parameter specifies the upper 32 bits for the 296 * number of logical block addresses for the device. The upper 297 * 16-bits should always be 0, since 48-bits of LBA is the most 298 * supported by an ATA device. 299 * @param[out] lba_low This parameter specifies the lower 32 bits for the 300 * number of logical block addresses for the device. 301 * @param[out] sector_size This parameter specifies the 32-bits of sector 302 * size. If the ATA device doesn't support reporting it's 303 * sector size, then 512 bytes is utilized as the default value. 304 * 305 * @return none 306 */ 307 void sati_ata_identify_device_get_sector_info( 308 ATA_IDENTIFY_DEVICE_DATA_T * identify, 309 U32 * lba_high, 310 U32 * lba_low, 311 U32 * sector_size 312 ) 313 { 314 // Calculate the values to be returned 315 // Calculation will be different if the SATA device supports 316 // 48-bit addressing. Bit 10 of Word 86 of ATA Identify 317 if (identify->command_set_enabled1 318 & ATA_IDENTIFY_COMMAND_SET_SUPPORTED1_48BIT_ENABLE) 319 { 320 // This drive supports 48-bit addressing 321 322 *lba_high = identify->max_48bit_lba[7] << 24; 323 *lba_high |= identify->max_48bit_lba[6] << 16; 324 *lba_high |= identify->max_48bit_lba[5] << 8; 325 *lba_high |= identify->max_48bit_lba[4]; 326 327 *lba_low = identify->max_48bit_lba[3] << 24; 328 *lba_low |= identify->max_48bit_lba[2] << 16; 329 *lba_low |= identify->max_48bit_lba[1] << 8; 330 *lba_low |= identify->max_48bit_lba[0]; 331 } 332 else 333 { 334 // This device doesn't support 48-bit addressing 335 // Pull out the largest LBA from words 60 and 61. 336 *lba_high = 0; 337 *lba_low = identify->total_num_sectors[3] << 24; 338 *lba_low |= identify->total_num_sectors[2] << 16; 339 *lba_low |= identify->total_num_sectors[1] << 8; 340 *lba_low |= identify->total_num_sectors[0]; 341 } 342 343 // If the ATA device reports its sector size (bit 12 of Word 106), 344 // then use that instead. 345 if (identify->physical_logical_sector_info 346 & ATA_IDENTIFY_SECTOR_LARGER_THEN_512_ENABLE) 347 { 348 *sector_size = identify->words_per_logical_sector[3] << 24; 349 *sector_size |= identify->words_per_logical_sector[2] << 16; 350 *sector_size |= identify->words_per_logical_sector[1] << 8; 351 *sector_size |= identify->words_per_logical_sector[0]; 352 } 353 else 354 { 355 // Default the sector size to 512 bytes 356 *sector_size = 512; 357 } 358 } 359 360 /** 361 * @brief This method will construct the ATA check power mode command. 362 * 363 * @pre It is expected that the user has properly set the current contents 364 * of the register FIS to 0. 365 * 366 * @param[out] ata_io This parameter specifies the ATA IO request structure 367 * for which to build the CHECK POWER MODE command. 368 * @param[in] sequence This parameter specifies the translator sequence 369 * for which the command is being constructed. 370 * 371 * @return none. 372 */ 373 void sati_ata_check_power_mode_construct( 374 void * ata_io, 375 SATI_TRANSLATOR_SEQUENCE_T * sequence 376 ) 377 { 378 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 379 380 sati_set_ata_command(register_fis, ATA_CHECK_POWER_MODE); 381 sati_ata_non_data_command(ata_io, sequence); 382 } 383 384 /** 385 * @brief This method is utilized to set a specific byte in the sense 386 * data area. It will ensure that the supplied byte offset 387 * isn't larger then the length of the requested sense data. 388 * 389 * @param[in] scsi_io This parameter specifies the user SCSI IO request 390 * for which to set the sense data byte. 391 * @param[in] byte_offset This parameter specifies the byte offset into 392 * the sense data buffer where the data should be written. 393 * @param[in] value This parameter specifies the 8-bit value to be written 394 * into the sense data area. 395 * 396 * @return none 397 */ 398 void sati_set_sense_data_byte( 399 U8 * sense_data, 400 U32 max_sense_data_len, 401 U32 byte_offset, 402 U8 value 403 ) 404 { 405 // Ensure that we don't attempt to write past the end of the sense 406 // data buffer. 407 if (byte_offset < max_sense_data_len) 408 sense_data[byte_offset] = value; 409 } 410 411 /** 412 * @brief This method will construct the common response IU in the user 413 * request's response IU location. 414 * 415 * @param[out] rsp_iu This parameter specifies the user request's 416 * response IU to be constructed. 417 * @param[in] scsi_status This parameter specifies the SCSI status 418 * value for the user's IO request. 419 * @param[in] sense_data_length This parameter specifies the sense data 420 * length for response IU. 421 * @param[in] data_present The parameter specifies the specific 422 * data present value for response IU. 423 * 424 * @return none 425 */ 426 void sati_scsi_common_response_iu_construct( 427 SCI_SSP_RESPONSE_IU_T * rsp_iu, 428 U8 scsi_status, 429 U8 sense_data_length, 430 U8 data_present 431 ) 432 { 433 rsp_iu->sense_data_length[3] = sense_data_length; 434 rsp_iu->sense_data_length[2] = 0; 435 rsp_iu->sense_data_length[1] = 0; 436 rsp_iu->sense_data_length[0] = 0; 437 rsp_iu->status = scsi_status; 438 rsp_iu->data_present = data_present; 439 } 440 441 /** 442 * @brief This method will construct the buffer for sense data 443 * sense data buffer location. Additionally, it will set the user's 444 * SCSI status. 445 * 446 * @param[in,out] scsi_io This parameter specifies the user's IO request 447 * for which to construct the buffer for sense data. 448 * @param[in] scsi_status This parameter specifies the SCSI status 449 * value for the user's IO request. 450 * @param[out] sense_data This parameter 451 * 452 * @return none 453 */ 454 static 455 void sati_scsi_get_sense_data_buffer( 456 SATI_TRANSLATOR_SEQUENCE_T * sequence, 457 void * scsi_io, 458 U8 scsi_status, 459 U8 ** sense_data, 460 U32 * sense_len) 461 { 462 #ifdef SATI_TRANSPORT_SUPPORTS_SAS 463 SCI_SSP_RESPONSE_IU_T * rsp_iu = (SCI_SSP_RESPONSE_IU_T*) 464 sati_cb_get_response_iu_address(scsi_io); 465 466 sati_scsi_common_response_iu_construct( 467 rsp_iu, 468 scsi_status, 469 sati_scsi_get_sense_data_length(sequence, scsi_io), 470 SCSI_RESPONSE_DATA_PRES_SENSE_DATA 471 ); 472 473 *sense_data = (U8*) rsp_iu->data; 474 *sense_len = SSP_RESPONSE_IU_MAX_DATA * 4; // dwords to bytes 475 #else 476 *sense_data = sati_cb_get_sense_data_address(scsi_io); 477 *sense_len = sati_cb_get_sense_data_length(scsi_io); 478 sati_cb_set_scsi_status(scsi_io, scsi_status); 479 #endif // SATI_TRANSPORT_SUPPORTS_SAS 480 } 481 482 /** 483 * @brief This method extract response code based on on device settings. 484 * 485 * @return response code 486 */ 487 static 488 U8 sati_scsi_get_sense_data_response_code(SATI_TRANSLATOR_SEQUENCE_T * sequence) 489 { 490 if (sequence->device->descriptor_sense_enable) 491 { 492 return SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE; 493 } 494 else 495 { 496 return SCSI_FIXED_CURRENT_RESPONSE_CODE; 497 } 498 } 499 500 /** 501 * @brief This method will return length of descriptor sense data for executed command. 502 * 503 * @return sense data length 504 */ 505 static 506 U8 sati_scsi_get_descriptor_sense_data_length(SATI_TRANSLATOR_SEQUENCE_T * sequence, 507 void * scsi_io) 508 { 509 U8 * cdb = sati_cb_get_cdb_address(scsi_io); 510 //Initial value is descriptor header length 511 U8 length = 8; 512 513 switch (sati_get_cdb_byte(cdb, 0)) 514 { 515 #if !defined(DISABLE_SATI_WRITE_LONG) 516 case SCSI_WRITE_LONG_10: 517 case SCSI_WRITE_LONG_16: 518 length += SCSI_BLOCK_DESCRIPTOR_LENGTH + 519 SCSI_INFORMATION_DESCRIPTOR_LENGTH; 520 break; 521 #endif // !defined(DISABLE_SATI_WRITE_LONG) 522 #if !defined(DISABLE_SATI_REASSIGN_BLOCKS) 523 case SCSI_REASSIGN_BLOCKS: 524 length += SCSI_CMD_SPECIFIC_DESCRIPTOR_LENGTH + 525 SCSI_INFORMATION_DESCRIPTOR_LENGTH; 526 break; 527 #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS) 528 case SCSI_READ_6: 529 case SCSI_READ_10: 530 case SCSI_READ_12: 531 case SCSI_READ_16: 532 case SCSI_WRITE_6: 533 case SCSI_WRITE_10: 534 case SCSI_WRITE_12: 535 case SCSI_WRITE_16: 536 #if !defined(DISABLE_SATI_VERIFY) 537 case SCSI_VERIFY_10: 538 case SCSI_VERIFY_12: 539 case SCSI_VERIFY_16: 540 #endif // !defined(DISABLE_SATI_VERIFY) 541 #if !defined(DISABLE_SATI_WRITE_AND_VERIFY) \ 542 && !defined(DISABLE_SATI_VERIFY) \ 543 && !defined(DISABLE_SATI_WRITE) 544 545 case SCSI_WRITE_AND_VERIFY_10: 546 case SCSI_WRITE_AND_VERIFY_12: 547 case SCSI_WRITE_AND_VERIFY_16: 548 #endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY) 549 // && !defined(DISABLE_SATI_VERIFY) 550 // && !defined(DISABLE_SATI_WRITE) 551 length += SCSI_INFORMATION_DESCRIPTOR_LENGTH; 552 break; 553 } 554 555 return length; 556 } 557 558 /** 559 * @brief This method will return length of sense data. 560 * 561 * @return sense data length 562 */ 563 U8 sati_scsi_get_sense_data_length(SATI_TRANSLATOR_SEQUENCE_T * sequence, void * scsi_io) 564 { 565 U8 response_code; 566 567 response_code = sati_scsi_get_sense_data_response_code(sequence); 568 569 switch (response_code) 570 { 571 case SCSI_FIXED_CURRENT_RESPONSE_CODE: 572 case SCSI_FIXED_DEFERRED_RESPONSE_CODE: 573 return SCSI_FIXED_SENSE_DATA_BASE_LENGTH; 574 break; 575 case SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE: 576 case SCSI_DESCRIPTOR_DEFERRED_RESPONSE_CODE: 577 return sati_scsi_get_descriptor_sense_data_length(sequence, scsi_io); 578 break; 579 } 580 581 return SCSI_FIXED_SENSE_DATA_BASE_LENGTH; 582 } 583 584 /** 585 * @brief This method will construct the sense data buffer in the user's 586 * sense data buffer location. Additionally, it will set the user's 587 * SCSI status. 588 * 589 * @param[in] sequence This parameter specifies the translation sequence 590 * for which to construct the sense data. 591 * @param[in,out] scsi_io This parameter specifies the user's IO request 592 * for which to construct the sense data. 593 * @param[in] scsi_status This parameter specifies the SCSI status 594 * value for the user's IO request. 595 * @param[in] sense_key This parameter specifies the sense key to 596 * be set for the user's IO request. 597 * @param[in] additional_sense_code This parameter specifies the 598 * additional sense code (ASC) key to be set for the user's 599 * IO request. 600 * @param[in] additional_sense_code_qualifier This parameter specifies 601 * the additional sense code qualifier (ASCQ) key to be set 602 * for the user's IO request. 603 * 604 * @return none 605 */ 606 void sati_scsi_sense_data_construct( 607 SATI_TRANSLATOR_SEQUENCE_T * sequence, 608 void * scsi_io, 609 U8 scsi_status, 610 U8 sense_key, 611 U8 additional_sense_code, 612 U8 additional_sense_code_qualifier 613 ) 614 { 615 U8 response_code; 616 617 response_code = sati_scsi_get_sense_data_response_code(sequence); 618 619 switch (response_code) 620 { 621 case SCSI_FIXED_CURRENT_RESPONSE_CODE: 622 case SCSI_FIXED_DEFERRED_RESPONSE_CODE: 623 sati_scsi_fixed_sense_data_construct(sequence, scsi_io, scsi_status, response_code, 624 sense_key, additional_sense_code, additional_sense_code_qualifier); 625 break; 626 case SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE: 627 case SCSI_DESCRIPTOR_DEFERRED_RESPONSE_CODE: 628 sati_scsi_descriptor_sense_data_construct(sequence, scsi_io, scsi_status, response_code, 629 sense_key, additional_sense_code, additional_sense_code_qualifier); 630 break; 631 } 632 633 sequence->is_sense_response_set = TRUE; 634 } 635 636 /** 637 * @brief This method will construct the block descriptor in the user's descriptor 638 * sense data buffer location. 639 * 640 * @param[in] sense_data This parameter specifies the user SCSI IO request 641 * for which to set the sense data byte. 642 * @param[in] sense_len This parameter specifies length of the sense data 643 * to be returned by SATI. 644 * @param[out] descriptor_len This parameter returns the length of constructed 645 * descriptor. 646 * 647 * @return none 648 */ 649 static 650 void sati_scsi_block_descriptor_construct( 651 U8 * sense_data, 652 U32 sense_len) 653 { 654 U8 ili = 1; 655 656 sati_set_sense_data_byte(sense_data, sense_len, 0, SCSI_BLOCK_DESCRIPTOR_TYPE); 657 sati_set_sense_data_byte(sense_data, sense_len, 1, SCSI_BLOCK_DESCRIPTOR_ADDITIONAL_LENGTH); 658 sati_set_sense_data_byte(sense_data, sense_len, 2, 0); 659 sati_set_sense_data_byte(sense_data, sense_len, 3, (ili << 5)); 660 } 661 662 /** 663 * @brief This method will construct the command-specific descriptor for 664 * the descriptor sense data buffer in the user's sense data buffer 665 * location. 666 * 667 * @param[in] sense_data This parameter specifies the user SCSI IO request 668 * for which to set the sense data byte. 669 * @param[in] sense_len This parameter specifies length of the sense data 670 * to be returned by SATI. 671 * @param[out] descriptor_len This parameter returns the length of constructed 672 * descriptor. 673 * @param[in] information_buff This parameter specifies the address for which 674 * to set the command-specific information buffer. 675 * 676 * @return none 677 */ 678 static 679 void sati_scsi_command_specific_descriptor_construct( 680 U8 * sense_data, 681 U32 sense_len, 682 U8 * information_buff) 683 { 684 U8 i; 685 686 sati_set_sense_data_byte(sense_data, sense_len, 0, SCSI_CMD_SPECIFIC_DESCRIPTOR_TYPE); 687 sati_set_sense_data_byte(sense_data, sense_len, 1, SCSI_CMD_SPECIFIC_DESCRIPTOR_ADDITIONAL_LENGTH); 688 sati_set_sense_data_byte(sense_data, sense_len, 2, 0); 689 sati_set_sense_data_byte(sense_data, sense_len, 3, 0); 690 691 // fill information buffer 692 // SBC 5.20.1 REASSIGN BLOCKS command overview 693 // If information about the first LBA not reassigned is not available 694 // COMMAND-SPECIFIC INFORMATION field shall be set to FFFF_FFFF_FFFF_FFFFh 695 for (i=0; i<8; i++) 696 sati_set_sense_data_byte(sense_data, sense_len, 4 + i, information_buff==NULL?0xFF:information_buff[i]); 697 } 698 699 /** 700 * @brief This method will construct the information descriptor for 701 * the descriptor sense data buffer in the user's sense data buffer 702 * location. 703 * 704 * @param[in] sense_data This parameter specifies the user SCSI IO request 705 * for which to set the sense data byte. 706 * @param[in] sense_len This parameter specifies length of the sense data 707 * to be returned by SATI. 708 * @param[out] descriptor_len This parameter returns the length of constructed 709 * descriptor. 710 * @param[in] information_buff This parameter specifies the address for which 711 * to set the information buffer. 712 * 713 * @return none 714 */ 715 static 716 void sati_scsi_information_descriptor_construct( 717 U8 * sense_data, 718 U32 sense_len, 719 U8 * information_buff) 720 { 721 U8 i; 722 U8 valid = 1; 723 724 sati_set_sense_data_byte(sense_data, sense_len, 0, SCSI_INFORMATION_DESCRIPTOR_TYPE); 725 sati_set_sense_data_byte(sense_data, sense_len, 1, SCSI_INFORMATION_DESCRIPTOR_ADDITIONAL_LENGTH); 726 sati_set_sense_data_byte(sense_data, sense_len, 2, (valid << 7)); 727 sati_set_sense_data_byte(sense_data, sense_len, 3, 0); 728 729 // fill information buffer 730 for (i=0; i<8; i++) 731 sati_set_sense_data_byte(sense_data, sense_len, 4 + i, information_buff==NULL?0:information_buff[i]); 732 } 733 734 /** 735 * @brief This method will construct the descriptors in the user's descriptor 736 * sense data buffer location. 737 * 738 * @param[in,out] scsi_io This parameter specifies the user's IO request 739 * for which to construct the sense data. 740 * @param[in] sense_data This parameter specifies the user SCSI IO request 741 * for which to set the sense data byte. 742 * @param[in] sense_len This parameter specifies length of the sense data 743 * to be returned by SATI. 744 * @param[out] descriptor_len This parameter returns the length of constructed 745 * descriptor. 746 * @param[in] information_buff This parameter specifies the address for which 747 * to set the information buffer. 748 * 749 * @return none 750 */ 751 static 752 void sati_scsi_common_descriptors_construct( 753 void * scsi_io, 754 U8 * sense_data, 755 U32 sense_len, 756 U8 * information_buff) 757 { 758 U8 * cdb = sati_cb_get_cdb_address(scsi_io); 759 U8 offset = 0; 760 761 switch (sati_get_cdb_byte(cdb, 0)) 762 { 763 #if !defined(DISABLE_SATI_WRITE_LONG) 764 case SCSI_WRITE_LONG_10: 765 case SCSI_WRITE_LONG_16: 766 sati_scsi_block_descriptor_construct( 767 sense_data + offset, 768 sense_len - offset); 769 770 offset += SCSI_BLOCK_DESCRIPTOR_LENGTH; 771 sati_scsi_information_descriptor_construct( 772 sense_data + offset, 773 sense_len - offset, 774 information_buff); 775 776 offset += SCSI_INFORMATION_DESCRIPTOR_LENGTH; 777 break; 778 #endif // !defined(DISABLE_SATI_WRITE_LONG) 779 #if !defined(DISABLE_SATI_REASSIGN_BLOCKS) 780 case SCSI_REASSIGN_BLOCKS: 781 sati_scsi_command_specific_descriptor_construct( 782 sense_data + offset, 783 sense_len - offset, 784 NULL); 785 786 offset += SCSI_CMD_SPECIFIC_DESCRIPTOR_LENGTH; 787 sati_scsi_information_descriptor_construct( 788 sense_data + offset, 789 sense_len - offset, 790 information_buff); 791 792 offset += SCSI_INFORMATION_DESCRIPTOR_LENGTH; 793 break; 794 #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS) 795 case SCSI_READ_6: 796 case SCSI_READ_10: 797 case SCSI_READ_12: 798 case SCSI_READ_16: 799 case SCSI_WRITE_6: 800 case SCSI_WRITE_10: 801 case SCSI_WRITE_12: 802 case SCSI_WRITE_16: 803 #if !defined(DISABLE_SATI_VERIFY) 804 case SCSI_VERIFY_10: 805 case SCSI_VERIFY_12: 806 case SCSI_VERIFY_16: 807 #endif // !defined(DISABLE_SATI_VERIFY) 808 #if !defined(DISABLE_SATI_WRITE_AND_VERIFY) \ 809 && !defined(DISABLE_SATI_VERIFY) \ 810 && !defined(DISABLE_SATI_WRITE) 811 812 case SCSI_WRITE_AND_VERIFY_10: 813 case SCSI_WRITE_AND_VERIFY_12: 814 case SCSI_WRITE_AND_VERIFY_16: 815 #endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY) 816 // && !defined(DISABLE_SATI_VERIFY) 817 // && !defined(DISABLE_SATI_WRITE) 818 sati_scsi_information_descriptor_construct( 819 sense_data + offset, 820 sense_len - offset, 821 information_buff); 822 823 offset += SCSI_INFORMATION_DESCRIPTOR_LENGTH; 824 break; 825 } 826 } 827 828 /** 829 * @brief This method will construct the descriptor sense data buffer in 830 * the user's sense data buffer location. Additionally, it will set 831 * the user's SCSI status. 832 * 833 * @param[in] sequence This parameter specifies the translation sequence 834 * for which to construct the sense data. 835 * @param[in,out] scsi_io This parameter specifies the user's IO request 836 * for which to construct the sense data. 837 * @param[in] scsi_status This parameter specifies the SCSI status 838 * value for the user's IO request. 839 * @param[in] sense_key This parameter specifies the sense key to 840 * be set for the user's IO request. 841 * @param[in] additional_sense_code This parameter specifies the 842 * additional sense code (ASC) key to be set for the user's 843 * IO request. 844 * @param[in] additional_sense_code_qualifier This parameter specifies 845 * the additional sense code qualifier (ASCQ) key to be set 846 * for the user's IO request. 847 * 848 * @return none 849 */ 850 void sati_scsi_descriptor_sense_data_construct( 851 SATI_TRANSLATOR_SEQUENCE_T * sequence, 852 void * scsi_io, 853 U8 scsi_status, 854 U8 response_code, 855 U8 sense_key, 856 U8 additional_sense_code, 857 U8 additional_sense_code_qualifier 858 ) 859 { 860 U8 * sense_data; 861 U32 sense_len; 862 863 sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len); 864 865 sati_set_sense_data_byte( 866 sense_data, 867 sense_len, 868 0, 869 response_code 870 ); 871 872 sati_set_sense_data_byte(sense_data, sense_len, 1, sense_key); 873 sati_set_sense_data_byte(sense_data, sense_len, 2, additional_sense_code); 874 sati_set_sense_data_byte(sense_data, sense_len, 3, additional_sense_code_qualifier); 875 sati_set_sense_data_byte(sense_data, sense_len, 4, 0); 876 sati_set_sense_data_byte(sense_data, sense_len, 5, 0); 877 sati_set_sense_data_byte(sense_data, sense_len, 6, 0); 878 879 sati_scsi_common_descriptors_construct(scsi_io, sense_data + 8, sense_len, NULL); 880 881 sati_set_sense_data_byte(sense_data, sense_len, 7, sati_scsi_get_descriptor_sense_data_length(sequence, scsi_io) - 8); 882 } 883 884 /** 885 * @brief This method will construct the fixed format sense data buffer 886 * in the user's sense data buffer location. Additionally, it will 887 * set the user's SCSI status. 888 * 889 * @param[in] sequence This parameter specifies the translation sequence 890 * for which to construct the sense data. 891 * @param[in,out] scsi_io This parameter specifies the user's IO request 892 * for which to construct the sense data. 893 * @param[in] scsi_status This parameter specifies the SCSI status 894 * value for the user's IO request. 895 * @param[in] sense_key This parameter specifies the sense key to 896 * be set for the user's IO request. 897 * @param[in] additional_sense_code This parameter specifies the 898 * additional sense code (ASC) key to be set for the user's 899 * IO request. 900 * @param[in] additional_sense_code_qualifier This parameter specifies 901 * the additional sense code qualifier (ASCQ) key to be set 902 * for the user's IO request. 903 * 904 * @return none 905 */ 906 void sati_scsi_fixed_sense_data_construct( 907 SATI_TRANSLATOR_SEQUENCE_T * sequence, 908 void * scsi_io, 909 U8 scsi_status, 910 U8 response_code, 911 U8 sense_key, 912 U8 additional_sense_code, 913 U8 additional_sense_code_qualifier 914 ) 915 { 916 U8 * sense_data; 917 U32 sense_len; 918 919 sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len); 920 921 // Write out the sense data format per SPC-4. 922 // We utilize the fixed format sense data format. 923 924 sati_set_sense_data_byte( 925 sense_data, 926 sense_len, 927 0, 928 response_code | SCSI_FIXED_SENSE_DATA_VALID_BIT 929 ); 930 931 sati_set_sense_data_byte(sense_data, sense_len, 1, 0); 932 sati_set_sense_data_byte(sense_data, sense_len, 2, sense_key); 933 sati_set_sense_data_byte(sense_data, sense_len, 3, 0); 934 sati_set_sense_data_byte(sense_data, sense_len, 4, 0); 935 sati_set_sense_data_byte(sense_data, sense_len, 5, 0); 936 sati_set_sense_data_byte(sense_data, sense_len, 6, 0); 937 sati_set_sense_data_byte(sense_data, sense_len, 7, (sense_len < 18 ? sense_len - 1 : 17) - 7); 938 sati_set_sense_data_byte(sense_data, sense_len, 8, 0); 939 sati_set_sense_data_byte(sense_data, sense_len, 9, 0); 940 sati_set_sense_data_byte(sense_data, sense_len, 10, 0); 941 sati_set_sense_data_byte(sense_data, sense_len, 11, 0); 942 sati_set_sense_data_byte(sense_data, sense_len, 12, additional_sense_code); 943 sati_set_sense_data_byte(sense_data, sense_len, 13, additional_sense_code_qualifier); 944 sati_set_sense_data_byte(sense_data, sense_len, 14, 0); 945 sati_set_sense_data_byte(sense_data, sense_len, 15, 0); 946 sati_set_sense_data_byte(sense_data, sense_len, 16, 0); 947 sati_set_sense_data_byte(sense_data, sense_len, 17, 0); 948 } 949 950 /** 951 * @brief This method will construct common sense data that will be identical in 952 * both read error sense construct functions. 953 * sati_scsi_read_ncq_error_sense_construct, 954 * sati_scsi_read_error_sense_construct 955 * 956 * @param[in] sense_data This parameter specifies the user SCSI IO request 957 * for which to set the sense data byte. 958 * @param[in] sense_len This parameter specifies length of the sense data 959 * to be returned by SATI. 960 * @param[in] sense_key This parameter specifies the sense key to 961 * be set for the user's IO request. 962 * @param[in] additional_sense_code This parameter specifies the 963 * additional sense code (ASC) key to be set for the user's 964 * IO request. 965 * @param[in] additional_sense_code_qualifier This parameter specifies 966 * the additional sense code qualifier (ASCQ) key to be set 967 * for the user's IO request. 968 * 969 * @return none 970 */ 971 static 972 void sati_scsi_common_fixed_sense_construct( 973 U8 * sense_data, 974 U32 sense_len, 975 U8 sense_key, 976 U8 additional_sense_code, 977 U8 additional_sense_code_qualifier 978 ) 979 { 980 981 sati_set_sense_data_byte(sense_data, sense_len, 1, 0); 982 sati_set_sense_data_byte(sense_data, sense_len, 2, sense_key); 983 984 //Bytes 3, 4, 5, 6 are set in read_error_sense_construct functions 985 986 sati_set_sense_data_byte(sense_data, sense_len, 7, (sense_len < 18 ? sense_len - 1 : 17) - 7); 987 sati_set_sense_data_byte(sense_data, sense_len, 8, 0); 988 sati_set_sense_data_byte(sense_data, sense_len, 9, 0); 989 sati_set_sense_data_byte(sense_data, sense_len, 10, 0); 990 sati_set_sense_data_byte(sense_data, sense_len, 11, 0); 991 sati_set_sense_data_byte(sense_data, sense_len, 12, additional_sense_code); 992 sati_set_sense_data_byte(sense_data, sense_len, 13, additional_sense_code_qualifier); 993 sati_set_sense_data_byte(sense_data, sense_len, 14, 0); 994 sati_set_sense_data_byte(sense_data, sense_len, 15, 0x80); 995 sati_set_sense_data_byte(sense_data, sense_len, 16, 0); 996 sati_set_sense_data_byte(sense_data, sense_len, 17, 0); 997 } 998 999 /** 1000 * @brief This method will construct the descriptor sense data buffer in 1001 * the user's sense data buffer location. Additionally, it will set 1002 * the user's SCSI status. 1003 * 1004 * @param[in] sequence This parameter specifies the translation sequence 1005 * for which to construct the sense data. 1006 * @param[in,out] scsi_io This parameter specifies the user's IO request 1007 * for which to construct the sense data. 1008 * @param[in] scsi_status This parameter specifies the SCSI status 1009 * value for the user's IO request. 1010 * @param[in] sense_key This parameter specifies the sense key to 1011 * be set for the user's IO request. 1012 * @param[in] additional_sense_code This parameter specifies the 1013 * additional sense code (ASC) key to be set for the user's 1014 * IO request. 1015 * @param[in] additional_sense_code_qualifier This parameter specifies 1016 * the additional sense code qualifier (ASCQ) key to be set 1017 * for the user's IO request. 1018 * 1019 * @return none 1020 */ 1021 static 1022 void sati_scsi_common_descriptor_sense_construct( 1023 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1024 void * scsi_io, 1025 U8 * sense_data, 1026 U32 sense_len, 1027 U8 sense_key, 1028 U8 additional_sense_code, 1029 U8 additional_sense_code_qualifier, 1030 U8 * information_buff 1031 ) 1032 { 1033 sati_set_sense_data_byte(sense_data, sense_len, 1, sense_key); 1034 sati_set_sense_data_byte(sense_data, sense_len, 2, additional_sense_code); 1035 sati_set_sense_data_byte(sense_data, sense_len, 3, additional_sense_code_qualifier); 1036 sati_set_sense_data_byte(sense_data, sense_len, 4, 0); 1037 sati_set_sense_data_byte(sense_data, sense_len, 5, 0); 1038 sati_set_sense_data_byte(sense_data, sense_len, 6, 0); 1039 1040 sati_scsi_common_descriptors_construct(scsi_io, sense_data + 8, sense_len, information_buff); 1041 1042 sati_set_sense_data_byte(sense_data, sense_len, 7, sati_scsi_get_descriptor_sense_data_length(sequence, scsi_io) - 8); 1043 } 1044 1045 /** 1046 * @brief This method will construct the sense data buffer in the user's 1047 * descriptor sense data buffer location. Additionally, it will set 1048 * the user's SCSI status. This is only used for NCQ uncorrectable 1049 * read errors 1050 * 1051 * @param[in] sequence This parameter specifies the translation sequence 1052 * for which to construct the sense data. 1053 * @param[in,out] scsi_io This parameter specifies the user's IO request 1054 * for which to construct the sense data. 1055 * @param[in] ata_input_data This parameter specifies the user's ATA IO 1056 * response from a Read Log Ext command. 1057 * @param[in] scsi_status This parameter specifies the SCSI status 1058 * value for the user's IO request. 1059 * @param[in] sense_key This parameter specifies the sense key to 1060 * be set for the user's IO request. 1061 * @param[in] additional_sense_code This parameter specifies the 1062 * additional sense code (ASC) key to be set for the user's 1063 * IO request. 1064 * @param[in] additional_sense_code_qualifier This parameter specifies 1065 * the additional sense code qualifier (ASCQ) key to be set 1066 * for the user's IO request. 1067 * 1068 * @return none 1069 */ 1070 static 1071 void sati_scsi_read_ncq_error_descriptor_sense_construct( 1072 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1073 void * scsi_io, 1074 void * ata_input_data, 1075 U8 scsi_status, 1076 U8 response_code, 1077 U8 sense_key, 1078 U8 additional_sense_code, 1079 U8 additional_sense_code_qualifier 1080 ) 1081 { 1082 U8 * sense_data; 1083 U32 sense_len; 1084 1085 U8 information_buff[8] = {0}; 1086 1087 ATA_NCQ_COMMAND_ERROR_LOG_T * ncq_log = (ATA_NCQ_COMMAND_ERROR_LOG_T *) ata_input_data; 1088 1089 sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len); 1090 1091 sati_set_sense_data_byte( 1092 sense_data, 1093 sense_len, 1094 0, 1095 response_code 1096 ); 1097 1098 information_buff[2] = ncq_log->lba_47_40; 1099 information_buff[3] = ncq_log->lba_39_32; 1100 information_buff[4] = ncq_log->lba_31_24; 1101 information_buff[5] = ncq_log->lba_23_16; 1102 information_buff[6] = ncq_log->lba_15_8; 1103 information_buff[7] = ncq_log->lba_7_0; 1104 1105 sati_scsi_common_descriptor_sense_construct( 1106 sequence, 1107 scsi_io, 1108 sense_data, 1109 sense_len, 1110 sense_key, 1111 additional_sense_code, 1112 additional_sense_code_qualifier, 1113 information_buff 1114 ); 1115 } 1116 1117 /** 1118 * @brief This method will construct the sense data buffer in the user's 1119 * sense data buffer location. Additionally, it will set the user's 1120 * SCSI status. This is only used for NCQ uncorrectable read errors 1121 * 1122 * @param[in] sequence This parameter specifies the translation sequence 1123 * for which to construct the sense data. 1124 * @param[in,out] scsi_io This parameter specifies the user's IO request 1125 * for which to construct the sense data. 1126 * @param[in] ata_input_data This parameter specifies the user's ATA IO 1127 * response from a Read Log Ext command. 1128 * @param[in] scsi_status This parameter specifies the SCSI status 1129 * value for the user's IO request. 1130 * @param[in] sense_key This parameter specifies the sense key to 1131 * be set for the user's IO request. 1132 * @param[in] additional_sense_code This parameter specifies the 1133 * additional sense code (ASC) key to be set for the user's 1134 * IO request. 1135 * @param[in] additional_sense_code_qualifier This parameter specifies 1136 * the additional sense code qualifier (ASCQ) key to be set 1137 * for the user's IO request. 1138 * 1139 * @return none 1140 */ 1141 static 1142 void sati_scsi_read_ncq_error_fixed_sense_construct( 1143 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1144 void * scsi_io, 1145 void * ata_input_data, 1146 U8 scsi_status, 1147 U8 response_code, 1148 U8 sense_key, 1149 U8 additional_sense_code, 1150 U8 additional_sense_code_qualifier 1151 ) 1152 { 1153 U8 * sense_data; 1154 U32 sense_len; 1155 U8 valid = TRUE; 1156 1157 ATA_NCQ_COMMAND_ERROR_LOG_T * ncq_log = (ATA_NCQ_COMMAND_ERROR_LOG_T *) ata_input_data; 1158 1159 sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len); 1160 1161 if(ncq_log->lba_39_32 > 0) 1162 { 1163 valid = FALSE; 1164 } 1165 1166 sati_set_sense_data_byte( 1167 sense_data, 1168 sense_len, 1169 0, 1170 (valid << 7) | response_code 1171 ); 1172 1173 sati_set_sense_data_byte(sense_data, sense_len, 3, ncq_log->lba_31_24); 1174 sati_set_sense_data_byte(sense_data, sense_len, 4, ncq_log->lba_23_16); 1175 sati_set_sense_data_byte(sense_data, sense_len, 5, ncq_log->lba_15_8); 1176 sati_set_sense_data_byte(sense_data, sense_len, 6, ncq_log->lba_7_0); 1177 1178 sati_scsi_common_fixed_sense_construct( 1179 sense_data, 1180 sense_len, 1181 sense_key, 1182 additional_sense_code, 1183 additional_sense_code_qualifier 1184 ); 1185 } 1186 1187 void sati_scsi_read_ncq_error_sense_construct( 1188 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1189 void * scsi_io, 1190 void * ata_input_data, 1191 U8 scsi_status, 1192 U8 sense_key, 1193 U8 additional_sense_code, 1194 U8 additional_sense_code_qualifier 1195 ) 1196 { 1197 U8 response_code; 1198 1199 response_code = sati_scsi_get_sense_data_response_code(sequence); 1200 1201 switch (response_code) 1202 { 1203 case SCSI_FIXED_CURRENT_RESPONSE_CODE: 1204 case SCSI_FIXED_DEFERRED_RESPONSE_CODE: 1205 sati_scsi_read_ncq_error_fixed_sense_construct(sequence, scsi_io, ata_input_data, scsi_status, 1206 response_code, sense_key, additional_sense_code, additional_sense_code_qualifier); 1207 break; 1208 case SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE: 1209 case SCSI_DESCRIPTOR_DEFERRED_RESPONSE_CODE: 1210 sati_scsi_read_ncq_error_descriptor_sense_construct(sequence, scsi_io, ata_input_data, scsi_status, 1211 response_code, sense_key, additional_sense_code, additional_sense_code_qualifier); 1212 break; 1213 } 1214 1215 sequence->is_sense_response_set = TRUE; 1216 } 1217 1218 /** 1219 * @brief This method will construct the sense data buffer in the user's 1220 * sense data buffer location. Additionally, it will set the user's 1221 * SCSI status. This is used for uncorrectable read errors. 1222 * 1223 * @param[in] sequence This parameter specifies the translation sequence 1224 * for which to construct the sense data. 1225 * @param[in,out] scsi_io This parameter specifies the user's IO request 1226 * for which to construct the sense data. 1227 * @param[in] ata_io This parameter is a pointer to the ATA IO data used 1228 * to get the ATA register fis. 1229 * @param[in] scsi_status This parameter specifies the SCSI status 1230 * value for the user's IO request. 1231 * @param[in] sense_key This parameter specifies the sense key to 1232 * be set for the user's IO request. 1233 * @param[in] additional_sense_code This parameter specifies the 1234 * additional sense code (ASC) key to be set for the user's 1235 * IO request. 1236 * @param[in] additional_sense_code_qualifier This parameter specifies 1237 * the additional sense code qualifier (ASCQ) key to be set 1238 * for the user's IO request. 1239 * 1240 * @return none 1241 */ 1242 static 1243 void sati_scsi_read_error_descriptor_sense_construct( 1244 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1245 void * scsi_io, 1246 void * ata_io, 1247 U8 scsi_status, 1248 U8 response_code, 1249 U8 sense_key, 1250 U8 additional_sense_code, 1251 U8 additional_sense_code_qualifier 1252 ) 1253 { 1254 U8 * sense_data; 1255 U32 sense_len; 1256 U8 information_buff[8] = {0}; 1257 1258 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io); 1259 1260 sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len); 1261 1262 information_buff[2] = sati_get_ata_lba_high_ext(register_fis); 1263 information_buff[3] = sati_get_ata_lba_mid_ext(register_fis); 1264 information_buff[4] = sati_get_ata_lba_low_ext(register_fis); 1265 information_buff[5] = sati_get_ata_lba_high(register_fis); 1266 information_buff[6] = sati_get_ata_lba_mid(register_fis); 1267 information_buff[7] = sati_get_ata_lba_low(register_fis); 1268 1269 sati_set_sense_data_byte( 1270 sense_data, 1271 sense_len, 1272 0, 1273 SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE 1274 ); 1275 1276 sati_scsi_common_descriptor_sense_construct( 1277 sequence, 1278 scsi_io, 1279 sense_data, 1280 sense_len, 1281 sense_key, 1282 additional_sense_code, 1283 additional_sense_code_qualifier, 1284 information_buff 1285 ); 1286 } 1287 1288 /** 1289 * @brief This method will construct the sense data buffer in the user's 1290 * sense data buffer location. Additionally, it will set the user's 1291 * SCSI status. This is used for uncorrectable read errors. 1292 * 1293 * @param[in] sequence This parameter specifies the translation sequence 1294 * for which to construct the sense data. 1295 * @param[in,out] scsi_io This parameter specifies the user's IO request 1296 * for which to construct the sense data. 1297 * @param[in] ata_io This parameter is a pointer to the ATA IO data used 1298 * to get the ATA register fis. 1299 * @param[in] scsi_status This parameter specifies the SCSI status 1300 * value for the user's IO request. 1301 * @param[in] sense_key This parameter specifies the sense key to 1302 * be set for the user's IO request. 1303 * @param[in] additional_sense_code This parameter specifies the 1304 * additional sense code (ASC) key to be set for the user's 1305 * IO request. 1306 * @param[in] additional_sense_code_qualifier This parameter specifies 1307 * the additional sense code qualifier (ASCQ) key to be set 1308 * for the user's IO request. 1309 * 1310 * @return none 1311 */ 1312 static 1313 void sati_scsi_read_error_fixed_sense_construct( 1314 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1315 void * scsi_io, 1316 void * ata_io, 1317 U8 scsi_status, 1318 U8 response_code, 1319 U8 sense_key, 1320 U8 additional_sense_code, 1321 U8 additional_sense_code_qualifier 1322 ) 1323 { 1324 U8 * sense_data; 1325 U32 sense_len; 1326 U8 valid = TRUE; 1327 1328 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io); 1329 1330 sati_scsi_get_sense_data_buffer(sequence, scsi_io, scsi_status, &sense_data, &sense_len); 1331 1332 if(sati_get_ata_lba_mid_ext(register_fis) > 0) 1333 { 1334 valid = FALSE; 1335 } 1336 1337 sati_set_sense_data_byte(sense_data, sense_len, 3, sati_get_ata_lba_low_ext(register_fis)); 1338 sati_set_sense_data_byte(sense_data, sense_len, 4, sati_get_ata_lba_high(register_fis)); 1339 sati_set_sense_data_byte(sense_data, sense_len, 5, sati_get_ata_lba_mid(register_fis)); 1340 sati_set_sense_data_byte(sense_data, sense_len, 6, sati_get_ata_lba_low(register_fis)); 1341 1342 1343 sati_set_sense_data_byte( 1344 sense_data, 1345 sense_len, 1346 0, 1347 (valid << 7) | SCSI_FIXED_CURRENT_RESPONSE_CODE 1348 ); 1349 1350 sati_scsi_common_fixed_sense_construct( 1351 sense_data, 1352 sense_len, 1353 sense_key, 1354 additional_sense_code, 1355 additional_sense_code_qualifier 1356 ); 1357 } 1358 1359 void sati_scsi_read_error_sense_construct( 1360 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1361 void * scsi_io, 1362 void * ata_input_data, 1363 U8 scsi_status, 1364 U8 sense_key, 1365 U8 additional_sense_code, 1366 U8 additional_sense_code_qualifier 1367 ) 1368 { 1369 U8 response_code; 1370 1371 response_code = sati_scsi_get_sense_data_response_code(sequence); 1372 1373 switch (response_code) 1374 { 1375 case SCSI_FIXED_CURRENT_RESPONSE_CODE: 1376 case SCSI_FIXED_DEFERRED_RESPONSE_CODE: 1377 sati_scsi_read_error_fixed_sense_construct(sequence, scsi_io, ata_input_data, scsi_status, 1378 response_code, sense_key, additional_sense_code, additional_sense_code_qualifier); 1379 break; 1380 case SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE: 1381 case SCSI_DESCRIPTOR_DEFERRED_RESPONSE_CODE: 1382 sati_scsi_read_error_descriptor_sense_construct(sequence, scsi_io, ata_input_data, scsi_status, 1383 response_code, sense_key, additional_sense_code, additional_sense_code_qualifier); 1384 break; 1385 } 1386 1387 sequence->is_sense_response_set = TRUE; 1388 } 1389 1390 /* 1391 * @brief This method builds the scsi response data for a sata task management 1392 * request. 1393 * 1394 * @param[in] sequence This parameter specifies the translation sequence 1395 * for which to construct the sense data. 1396 * @param[in,out] scsi_io This parameter specifies the user's IO request 1397 * for which to construct the sense data. 1398 * @param[in] response_data The response status for the task management 1399 * request. 1400 */ 1401 void sati_scsi_response_data_construct( 1402 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1403 void * scsi_io, 1404 U8 response_data 1405 ) 1406 { 1407 #ifdef SATI_TRANSPORT_SUPPORTS_SAS 1408 SCI_SSP_RESPONSE_IU_T * rsp_iu = (SCI_SSP_RESPONSE_IU_T*) 1409 sati_cb_get_response_iu_address(scsi_io); 1410 rsp_iu->data_present = 0x01; 1411 rsp_iu->response_data_length[3] = sizeof(U32); 1412 rsp_iu->status = 0; 1413 ((U8 *)rsp_iu->data)[3] = response_data; 1414 #else 1415 #endif // SATI_TRANSPORT_SUPPORTS_SAS 1416 } 1417 1418 /** 1419 * @brief This method checks to make sure that the translation isn't 1420 * exceeding the allocation length specified in the CDB prior 1421 * to retrieving the payload data byte from the user's buffer. 1422 * 1423 * @param[in,out] scsi_io This parameter specifies the user's IO request 1424 * for which to set the user payload data byte. 1425 * @param[in] byte_offset This parameter specifies the offset into 1426 * the user's payload buffer at which to write the supplied 1427 * value. 1428 * @param[in] value This parameter specifies the memory location into 1429 * which to read the value from the user's payload buffer. 1430 * 1431 * @return none 1432 */ 1433 void sati_get_data_byte( 1434 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1435 void * scsi_io, 1436 U32 byte_offset, 1437 U8 * value 1438 ) 1439 { 1440 if (byte_offset < sequence->allocation_length) 1441 sati_cb_get_data_byte(scsi_io, byte_offset, value); 1442 } 1443 1444 /** 1445 * @brief This method checks to make sure that the translation isn't 1446 * exceeding the allocation length specified in the CDB while 1447 * translating payload data into the user's buffer. 1448 * 1449 * @param[in] sequence This parameter specifies the translation sequence 1450 * for which to set the user payload data byte. 1451 * @param[in,out] scsi_io This parameter specifies the user's IO request 1452 * for which to set the user payload data byte. 1453 * @param[in] byte_offset This parameter specifies the offset into 1454 * the user's payload buffer at which to write the supplied 1455 * value. 1456 * @param[in] value This parameter specifies the new value to be 1457 * written out into the user's payload buffer. 1458 * 1459 * @return none 1460 */ 1461 void sati_set_data_byte( 1462 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1463 void * scsi_io, 1464 U32 byte_offset, 1465 U8 value 1466 ) 1467 { 1468 if (byte_offset < sequence->allocation_length) 1469 { 1470 sequence->number_data_bytes_set++; 1471 sati_cb_set_data_byte(scsi_io, byte_offset, value); 1472 } 1473 } 1474 1475 /** 1476 * @brief This method checks to make sure that the translation isn't 1477 * exceeding the allocation length specified in the CDB while 1478 * translating payload data into the user's buffer. 1479 * 1480 * @param[in] sequence This parameter specifies the translation sequence 1481 * for which to set the user payload data dword. 1482 * @param[in,out] scsi_io This parameter specifies the user's IO request 1483 * for which to set the user payload data dword. 1484 * @param[in] byte_offset This parameter specifies the offset into 1485 * the user's payload buffer at which to write the supplied 1486 * value. 1487 * @param[in] value This parameter specifies the new value to be 1488 * written out into the user's payload buffer. 1489 * 1490 * @return none 1491 */ 1492 void sati_set_data_dword( 1493 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1494 void * scsi_io, 1495 U32 byte_offset, 1496 U32 value 1497 ) 1498 { 1499 /// @todo Check to ensure that the bytes appear correctly (SAS Address). 1500 1501 sati_set_data_byte(sequence, scsi_io, byte_offset, (U8)value & 0xFF); 1502 byte_offset++; 1503 sati_set_data_byte(sequence, scsi_io, byte_offset, (U8)(value >> 8) & 0xFF); 1504 byte_offset++; 1505 sati_set_data_byte(sequence, scsi_io, byte_offset, (U8)(value >> 16) & 0xFF); 1506 byte_offset++; 1507 sati_set_data_byte(sequence, scsi_io, byte_offset, (U8)(value >> 24) & 0xFF); 1508 } 1509 1510 /** 1511 * @brief This method will construct the ATA flush cache command. 1512 * 1513 * @pre It is expected that the user has properly set the current contents 1514 * of the register FIS to 0. 1515 * 1516 * @param[out] ata_io This parameter specifies the ATA IO request structure 1517 * for which to build the FLUSH CACHE command. 1518 * @param[in] sequence This parameter specifies the translator sequence 1519 * for which the command is being constructed. 1520 * 1521 * @return none. 1522 */ 1523 void sati_ata_flush_cache_construct( 1524 void * ata_io, 1525 SATI_TRANSLATOR_SEQUENCE_T * sequence 1526 ) 1527 { 1528 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1529 1530 sati_set_ata_command(register_fis, ATA_FLUSH_CACHE); 1531 sati_ata_non_data_command(ata_io, sequence); 1532 } 1533 1534 /** 1535 * @brief This method will construct the ATA standby immediate command. 1536 * 1537 * @pre It is expected that the user has properly set the current contents 1538 * of the register FIS to 0. 1539 * 1540 * @param[out] ata_io This parameter specifies the ATA IO request structure 1541 * for which to build the STANDBY IMMEDIATE command. 1542 * @param[in] sequence This parameter specifies the translator sequence 1543 * for which the command is being constructed. 1544 * 1545 * @param[in] count This parameter specifies the time period programmed 1546 * into the Standby Timer. See ATA8 spec for more details 1547 * @return none. 1548 */ 1549 void sati_ata_standby_construct( 1550 void * ata_io, 1551 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1552 U16 count 1553 ) 1554 { 1555 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1556 1557 sati_set_ata_command(register_fis, ATA_STANDBY); 1558 sati_set_ata_sector_count(register_fis, count); 1559 1560 sequence->device->ata_standby_timer = (U8) count; 1561 1562 sati_ata_non_data_command(ata_io, sequence); 1563 } 1564 1565 /** 1566 * @brief This method will construct the ATA standby immediate command. 1567 * 1568 * @pre It is expected that the user has properly set the current contents 1569 * of the register FIS to 0. 1570 * 1571 * @param[out] ata_io This parameter specifies the ATA IO request structure 1572 * for which to build the STANDBY IMMEDIATE command. 1573 * @param[in] sequence This parameter specifies the translator sequence 1574 * for which the command is being constructed. 1575 * 1576 * @return none. 1577 */ 1578 void sati_ata_standby_immediate_construct( 1579 void * ata_io, 1580 SATI_TRANSLATOR_SEQUENCE_T * sequence 1581 ) 1582 { 1583 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1584 1585 sati_set_ata_command(register_fis, ATA_STANDBY_IMMED); 1586 sati_ata_non_data_command(ata_io, sequence); 1587 } 1588 1589 /** 1590 * @brief This method will construct the ATA idle immediate command. 1591 * 1592 * @pre It is expected that the user has properly set the current contents 1593 * of the register FIS to 0. 1594 * 1595 * @param[out] ata_io This parameter specifies the ATA IO request structure 1596 * for which to build the IDLE IMMEDIATE command. 1597 * @param[in] sequence This parameter specifies the translator sequence 1598 * for which the command is being constructed. 1599 * 1600 * @return none. 1601 */ 1602 void sati_ata_idle_immediate_construct( 1603 void * ata_io, 1604 SATI_TRANSLATOR_SEQUENCE_T * sequence 1605 ) 1606 { 1607 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1608 1609 sati_set_ata_command(register_fis, ATA_IDLE_IMMED); 1610 sati_set_ata_features(register_fis, 0x00); 1611 sati_set_ata_sector_count(register_fis, 0x00); 1612 sati_set_ata_lba_high(register_fis, 0x00); 1613 sati_set_ata_lba_mid(register_fis, 0x00); 1614 sati_set_ata_lba_low(register_fis, 0x00); 1615 sati_ata_non_data_command(ata_io, sequence); 1616 } 1617 1618 /** 1619 * @brief This method will construct the ATA idle immediate command 1620 for Unload Features. 1621 * 1622 * @pre It is expected that the user has properly set the current contents 1623 * of the register FIS to 0. 1624 * 1625 * @param[out] ata_io This parameter specifies the ATA IO request structure 1626 * for which to build the IDLE IMMEDIATE command. 1627 * @param[in] sequence This parameter specifies the translator sequence 1628 * for which the command is being constructed. 1629 * 1630 * @return none. 1631 */ 1632 void sati_ata_idle_immediate_unload_construct( 1633 void * ata_io, 1634 SATI_TRANSLATOR_SEQUENCE_T * sequence 1635 ) 1636 { 1637 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1638 1639 sati_set_ata_command(register_fis, ATA_IDLE_IMMED); 1640 sati_set_ata_features(register_fis, 0x44); 1641 sati_set_ata_sector_count(register_fis, 0x00); 1642 sati_set_ata_lba_high(register_fis, 0x55); 1643 sati_set_ata_lba_mid(register_fis, 0x4E); 1644 sati_set_ata_lba_low(register_fis, 0x4C); 1645 sati_ata_non_data_command(ata_io, sequence); 1646 } 1647 1648 /** 1649 * @brief This method will construct the ATA IDLE command.\ 1650 * 1651 * @pre It is expected that the user has properly set the current contents 1652 * of the register FIS to 0. 1653 * 1654 * @param[out] ata_io This parameter specifies the ATA IO request structure 1655 * for which to build the ATA IDLE command. 1656 * @param[in] sequence This parameter specifies the translator sequence 1657 * for which the command is being constructed. 1658 * 1659 * @return none. 1660 */ 1661 void sati_ata_idle_construct( 1662 void * ata_io, 1663 SATI_TRANSLATOR_SEQUENCE_T * sequence 1664 ) 1665 { 1666 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1667 1668 sati_set_ata_command(register_fis, ATA_IDLE); 1669 sati_set_ata_features(register_fis, 0x00); 1670 sati_set_ata_sector_count(register_fis, 0x00); 1671 1672 sequence->device->ata_standby_timer = 0x00; 1673 1674 sati_set_ata_lba_high(register_fis, 0x00); 1675 sati_set_ata_lba_mid(register_fis, 0x00); 1676 sati_set_ata_lba_low(register_fis, 0x00); 1677 sati_ata_non_data_command(ata_io, sequence); 1678 } 1679 1680 /** 1681 * @brief This method will construct the ATA MEDIA EJECT command. 1682 * 1683 * @pre It is expected that the user has properly set the current contents 1684 * of the register FIS to 0. 1685 * 1686 * @param[out] ata_io This parameter specifies the ATA IO request structure 1687 * for which to build the MEDIA EJCT command. 1688 * @param[in] sequence This parameter specifies the translator sequence 1689 * for which the command is being constructed. 1690 * 1691 * @return none. 1692 */ 1693 void sati_ata_media_eject_construct( 1694 void * ata_io, 1695 SATI_TRANSLATOR_SEQUENCE_T * sequence 1696 ) 1697 { 1698 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1699 1700 sati_set_ata_command(register_fis, ATA_MEDIA_EJECT); 1701 sati_ata_non_data_command(ata_io, sequence); 1702 } 1703 1704 1705 /** 1706 * @brief This method will construct the ATA read verify sector(s) command. 1707 * 1708 * @pre It is expected that the user has properly set the current contents 1709 * of the register FIS to 0. 1710 * 1711 * @param[out] ata_io This parameter specifies the ATA IO request structure 1712 * for which to build the ATA READ VERIFY SECTOR(S) command. 1713 * @param[in] sequence This parameter specifies the translator sequence 1714 * for which the command is being constructed. 1715 * 1716 * @return none. 1717 */ 1718 void sati_ata_read_verify_sectors_construct( 1719 void * ata_io, 1720 SATI_TRANSLATOR_SEQUENCE_T * sequence 1721 ) 1722 { 1723 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1724 1725 sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS); 1726 1727 //According to SAT-2 (v7) 9.11.3 1728 sati_set_ata_sector_count(register_fis, 1); 1729 1730 //According to SAT-2 (v7) 9.11.3, set LBA to a value between zero and the 1731 //maximum LBA supported by the ATA device in its current configuration. 1732 //From the unit test, it seems we have to set LBA to a non-zero value. 1733 sati_set_ata_lba_low(register_fis, 1); 1734 1735 sati_ata_non_data_command(ata_io, sequence); 1736 } 1737 1738 /** 1739 * @brief This method will construct a ATA SMART Return Status command so the 1740 * status of the ATA device can be returned. The status of the SMART 1741 * threshold will be returned by this command. 1742 * 1743 * @return N/A 1744 * 1745 */ 1746 void sati_ata_smart_return_status_construct( 1747 void * ata_io, 1748 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1749 U8 feature_value 1750 ) 1751 { 1752 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1753 1754 sati_set_ata_command(register_fis, ATA_SMART); 1755 1756 sati_set_ata_features(register_fis, feature_value); 1757 1758 sati_set_ata_lba_high(register_fis, 0xC2); 1759 sati_set_ata_lba_mid(register_fis, 0x4F); 1760 1761 sati_ata_non_data_command(ata_io, sequence); 1762 } 1763 1764 /** 1765 * @brief This method will construct a ATA SMART Return Status command so the 1766 * status of the ATA device can be returned. The status of the SMART 1767 * threshold will be returned by this command. 1768 * 1769 * @return N/A 1770 * 1771 */ 1772 void sati_ata_smart_read_log_construct( 1773 void * ata_io, 1774 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1775 U8 log_address, 1776 U32 transfer_length 1777 ) 1778 { 1779 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1780 1781 sati_set_ata_command(register_fis, ATA_SMART); 1782 sati_set_ata_features(register_fis, ATA_SMART_SUB_CMD_READ_LOG); 1783 1784 sati_set_ata_lba_high(register_fis, 0xC2); 1785 sati_set_ata_lba_mid(register_fis, 0x4F); 1786 sati_set_ata_lba_low(register_fis, log_address); 1787 1788 sequence->data_direction = SATI_DATA_DIRECTION_IN; 1789 sequence->protocol = SAT_PROTOCOL_PIO_DATA_IN; 1790 sequence->ata_transfer_length = transfer_length; 1791 } 1792 1793 /** 1794 * @brief This method will construct a Write Uncorrectable ATA command that 1795 * will write one sector with a pseudo or flagged error. The type of 1796 * error is specified by the feature value. 1797 * 1798 * @return N/A 1799 * 1800 */ 1801 void sati_ata_write_uncorrectable_construct( 1802 void * ata_io, 1803 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1804 U8 feature_value 1805 ) 1806 { 1807 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1808 1809 sati_set_ata_command(register_fis, ATA_WRITE_UNCORRECTABLE); 1810 sati_set_ata_features(register_fis, feature_value); 1811 sati_set_ata_sector_count(register_fis, 0x0001); 1812 sati_ata_non_data_command(ata_io, sequence); 1813 } 1814 1815 /** 1816 * @brief This method will construct a Mode Select ATA SET FEATURES command 1817 * For example, Enable/Disable Write Cache, Enable/Disable Read Ahead 1818 * 1819 * @return N/A 1820 * 1821 */ 1822 void sati_ata_set_features_construct( 1823 void * ata_io, 1824 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1825 U8 feature 1826 ) 1827 { 1828 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1829 1830 sati_set_ata_command(register_fis, ATA_SET_FEATURES); 1831 sati_set_ata_features(register_fis, feature); 1832 sati_ata_non_data_command(ata_io, sequence); 1833 } 1834 1835 1836 1837 /** 1838 * @brief This method will construct a Read Log ext ATA command that 1839 * will request a log page based on the log_address. 1840 * 1841 * @param[in] log_address This parameter specifies the log page 1842 * to be returned from Read Log Ext. 1843 * 1844 * @param[in] transfer_length This parameter specifies the size of the 1845 * log page response returned by Read Log Ext. 1846 * 1847 * @return N/A 1848 * 1849 */ 1850 void sati_ata_read_log_ext_construct( 1851 void * ata_io, 1852 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1853 U8 log_address, 1854 U32 transfer_length 1855 ) 1856 { 1857 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1858 1859 sati_set_ata_command(register_fis, ATA_READ_LOG_EXT); 1860 1861 sati_set_ata_lba_low(register_fis, log_address); 1862 sati_set_ata_lba_mid(register_fis, 0x00); 1863 sati_set_ata_lba_mid_exp(register_fis, 0x00); 1864 1865 sati_set_ata_sector_count(register_fis, 0x01); 1866 1867 sequence->data_direction = SATI_DATA_DIRECTION_IN; 1868 sequence->protocol = SAT_PROTOCOL_PIO_DATA_IN; 1869 sequence->ata_transfer_length = transfer_length; 1870 1871 } 1872 1873 /** 1874 * @brief This method will check if the ATA device is in the stopped power 1875 * state. This is used for all medium access commands for SAT 1876 * compliance. See SAT2r07 section 9.11.1 1877 * 1878 * @param[in] sequence - SATI sequence data with the device state. 1879 * 1880 * @return TRUE If device is stopped 1881 * 1882 */ 1883 BOOL sati_device_state_stopped( 1884 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1885 void * scsi_io 1886 ) 1887 { 1888 if(sequence->device->state == SATI_DEVICE_STATE_STOPPED) 1889 { 1890 sati_scsi_sense_data_construct( 1891 sequence, 1892 scsi_io, 1893 SCSI_STATUS_CHECK_CONDITION, 1894 SCSI_SENSE_NOT_READY , 1895 SCSI_ASC_INITIALIZING_COMMAND_REQUIRED, 1896 SCSI_ASCQ_INITIALIZING_COMMAND_REQUIRED 1897 ); 1898 return TRUE; 1899 } 1900 return FALSE; 1901 } 1902 1903 /** 1904 * @brief This method will construct a ATA Read Buffer command that 1905 * will request PIO in data containing the target device's buffer. 1906 * 1907 * @param[out] ata_io This parameter specifies the ATA IO request structure 1908 * for which to build the ATA READ VERIFY SECTOR(S) command. 1909 * @param[in] sequence This parameter specifies the translator sequence 1910 * for which the command is being constructed. 1911 * @return N/A 1912 * 1913 */ 1914 void sati_ata_read_buffer_construct( 1915 void * ata_io, 1916 SATI_TRANSLATOR_SEQUENCE_T * sequence 1917 ) 1918 { 1919 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1920 1921 sati_set_ata_command(register_fis, ATA_READ_BUFFER); 1922 sequence->data_direction = SATI_DATA_DIRECTION_IN; 1923 sequence->protocol = SAT_PROTOCOL_PIO_DATA_IN; 1924 sequence->ata_transfer_length = 512; 1925 } 1926 1927 1928 /** 1929 * @brief This method will construct a ATA Write Buffer command that 1930 * will send PIO out data to the target device's buffer. 1931 * 1932 * @param[out] ata_io This parameter specifies the ATA IO request structure 1933 * for which to build the ATA READ VERIFY SECTOR(S) command. 1934 * @param[in] sequence This parameter specifies the translator sequence 1935 * for which the command is being constructed. 1936 * @return N/A 1937 * 1938 */ 1939 void sati_ata_write_buffer_construct( 1940 void * ata_io, 1941 SATI_TRANSLATOR_SEQUENCE_T * sequence 1942 ) 1943 { 1944 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1945 1946 sati_set_ata_command(register_fis, ATA_WRITE_BUFFER); 1947 1948 sequence->data_direction = SATI_DATA_DIRECTION_OUT; 1949 sequence->protocol = SAT_PROTOCOL_PIO_DATA_OUT; 1950 sequence->ata_transfer_length = 512; 1951 } 1952 1953 1954 /** 1955 * @brief This method will construct a ATA Download Microcode command that 1956 * will send PIO out data containing new firmware for the target drive. 1957 * 1958 * @param[out] ata_io This parameter specifies the ATA IO request structure 1959 * for which to build the ATA READ VERIFY SECTOR(S) command. 1960 * @param[in] sequence This parameter specifies the translator sequence 1961 * for which the command is being constructed. 1962 * @param[in] mode This parameter specifies the download microcode sub-command 1963 * code. 1964 * @param[in] allocation_length This parameter specifies the number of bytes 1965 * being sent to the target device. 1966 * @param[in] buffer_offset This parameter specifies the buffer offset for the 1967 * data sent to the target device. 1968 * 1969 * @return N/A 1970 * 1971 */ 1972 void sati_ata_download_microcode_construct( 1973 void * ata_io, 1974 SATI_TRANSLATOR_SEQUENCE_T * sequence, 1975 U8 mode, 1976 U32 allocation_length, 1977 U32 buffer_offset 1978 ) 1979 { 1980 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 1981 U32 allocation_blocks = allocation_length >> 9; 1982 U32 buffer_blkoffset = buffer_offset >> 9; 1983 1984 sati_set_ata_command(register_fis, ATA_DOWNLOAD_MICROCODE); 1985 sati_set_ata_features(register_fis, mode); 1986 1987 if(mode == ATA_MICROCODE_DOWNLOAD_SAVE) 1988 { 1989 sati_set_ata_sector_count(register_fis, (U8) (allocation_length >> 9)); 1990 sati_set_ata_lba_low(register_fis, (U8) (allocation_length >> 17)); 1991 } 1992 else //mode == 0x03 1993 { 1994 sati_set_ata_sector_count(register_fis, (U8) (allocation_blocks & 0xff)); 1995 sati_set_ata_lba_low(register_fis, (U8) ((allocation_blocks >> 8) & 0xff)); 1996 sati_set_ata_lba_mid(register_fis, (U8) (buffer_blkoffset & 0xff)); 1997 sati_set_ata_lba_high(register_fis, (U8) ((buffer_blkoffset >> 8) & 0xff)); 1998 } 1999 2000 if((allocation_length == 0) && (buffer_offset == 0)) 2001 { 2002 sati_ata_non_data_command(ata_io, sequence); 2003 } 2004 else 2005 { 2006 sequence->data_direction = SATI_DATA_DIRECTION_OUT; 2007 sequence->protocol = SAT_PROTOCOL_PIO_DATA_OUT; 2008 sequence->ata_transfer_length = allocation_length; 2009 } 2010 } 2011