1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0 3 * 4 * This file is provided under a dual BSD/GPLv2 license. When using or 5 * redistributing this file, you may do so under either license. 6 * 7 * GPL LICENSE SUMMARY 8 * 9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of version 2 of the GNU General Public License as 13 * published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 23 * The full GNU General Public License is included in this distribution 24 * in the file called LICENSE.GPL. 25 * 26 * BSD LICENSE 27 * 28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 34 * 35 * * Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * * Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in 39 * the documentation and/or other materials provided with the 40 * distribution. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 */ 54 55 #include <sys/cdefs.h> 56 __FBSDID("$FreeBSD$"); 57 58 /** 59 * @file 60 * @brief This file contains the method implementations required to 61 * translate the SCSI reassign blocks command. 62 */ 63 64 #if !defined(DISABLE_SATI_REASSIGN_BLOCKS) 65 66 #include <dev/isci/scil/sati_reassign_blocks.h> 67 #include <dev/isci/scil/sati_callbacks.h> 68 #include <dev/isci/scil/sati_move.h> 69 #include <dev/isci/scil/sati_write.h> 70 #include <dev/isci/scil/sati_translator_sequence.h> 71 #include <dev/isci/scil/sati_util.h> 72 #include <dev/isci/scil/intel_scsi.h> 73 74 75 //****************************************************************************** 76 //* P R I V A T E M E T H O D S 77 //****************************************************************************** 78 // static SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T reassign_blocks_processing_state; 79 80 /** 81 * @brief This method copies short 24bits LBA bytes to the command register 82 * @return Indicate if the method was successfully completed. 83 * @retval SATI_SUCCESS This is returned in all other cases. 84 */ 85 static 86 void set_current_lba(U8 * lba, void * ata_io) 87 { 88 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 89 90 sati_set_ata_lba_low(register_fis, lba[0]); 91 sati_set_ata_lba_mid(register_fis, lba[1]); 92 sati_set_ata_lba_high(register_fis, lba[2]); 93 sati_set_ata_device_head(register_fis, ATA_DEV_HEAD_REG_LBA_MODE_ENABLE | (lba[3] & 0x0F)); 94 95 96 } 97 98 /** 99 * @brief This method copies short 48bits LBA bytes to the command register 100 * @return Indicate if the method was successfully completed. 101 * @retval SATI_SUCCESS This is returned in all other cases. 102 */ 103 static 104 void set_current_long_lba(U8 * lba, void * ata_io) 105 { 106 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 107 108 sati_set_ata_lba_low(register_fis, lba[0]); 109 sati_set_ata_lba_mid(register_fis, lba[1]); 110 sati_set_ata_lba_high(register_fis, lba[2]); 111 sati_set_ata_lba_low_exp(register_fis, lba[3]); 112 sati_set_ata_lba_mid_exp(register_fis, lba[4]); 113 sati_set_ata_lba_high_exp(register_fis, lba[5]); 114 } 115 116 /** 117 * @brief This method performs the SCSI VERIFY command translation 118 * functionality. 119 * This includes: 120 * - setting the command register 121 * - setting the device head register 122 * - filling in fields in the SATI_TRANSLATOR_SEQUENCE object. 123 * For more information on the parameters passed to this method, 124 * please reference sati_translate_command(). 125 * 126 * @return Indicate if the method was successfully completed. 127 * @retval SATI_SUCCESS This is returned in all other cases. 128 */ 129 static 130 SATI_STATUS sati_reassign_blocks_verify_command( 131 SATI_TRANSLATOR_SEQUENCE_T * sequence, 132 void * scsi_io, 133 void * ata_io 134 ) 135 { 136 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 137 138 sati_ata_non_data_command(ata_io, sequence); 139 140 // Ensure the device supports the 48 bit feature set. 141 if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE) 142 sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS_EXT); 143 else 144 sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS); 145 146 return SATI_SUCCESS; 147 } 148 149 /** 150 * @brief This method performs the SCSI Write sector command translation 151 * functionality. 152 * This includes: 153 * - setting the command register 154 * - setting the device head register 155 * - filling in fields in the SATI_TRANSLATOR_SEQUENCE object. 156 * For more information on the parameters passed to this method, 157 * please reference sati_translate_command(). 158 * 159 * @return Indicate if the method was successfully completed. 160 * @retval SATI_SUCCESS This is returned in all other cases. 161 */ 162 static 163 SATI_STATUS sati_reassign_blocks_write_command( 164 SATI_TRANSLATOR_SEQUENCE_T * sequence, 165 void * scsi_io, 166 void * ata_io 167 ) 168 { 169 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 170 171 sati_ata_non_data_command(ata_io, sequence); 172 sequence->data_direction = SATI_DATA_DIRECTION_OUT; 173 174 // sati_set_ata_sector_count(register_fis, 1); 175 // status=sati_move_set_sector_count(sequence,scsi_io,ata_io,1,0); 176 177 // Ensure the device supports the 48 bit feature set. 178 if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE) 179 sati_set_ata_command(register_fis, ATA_WRITE_DMA_EXT); 180 else 181 sati_set_ata_command(register_fis, ATA_WRITE_DMA); 182 183 return SATI_SUCCESS; //sati_move_set_sector_count(sequence,scsi_io,ata_io,1,0); 184 } 185 186 /** 187 * @brief This method performs the retrieving of parameter LBA praparation and setting 188 * processing flags before/after calling SCSI Verify sector command. 189 * @return Indicate if the method was successfully completed. 190 * @retval SATI_SUCCESS This is returned in all other cases. 191 */ 192 static 193 SATI_STATUS sati_reassign_blocks_verify_condition( 194 SATI_TRANSLATOR_SEQUENCE_T * sequence, 195 void * scsi_io, 196 void * ata_io 197 ) 198 { 199 U8 current_lba_bytes[8] = {0,0,0,0,0,0,0,0}; 200 U32 lba_offset; 201 U8 page_size; 202 U32 index; 203 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 204 205 lba_offset = sequence->command_specific_data.reassign_blocks_process_state.lba_offset; 206 page_size = sequence->command_specific_data.reassign_blocks_process_state.lba_size; 207 208 for(index = 0; index < page_size; index++) 209 { 210 sati_get_data_byte(sequence, scsi_io, lba_offset+index, ¤t_lba_bytes[index]); 211 } 212 213 if (page_size == 4) 214 set_current_lba(current_lba_bytes, ata_io); 215 else 216 set_current_long_lba(current_lba_bytes, ata_io); 217 218 status = sati_reassign_blocks_verify_command(sequence, scsi_io, ata_io); 219 sequence->command_specific_data.reassign_blocks_process_state.ata_command_sent_for_current_lba++; 220 sequence->command_specific_data.reassign_blocks_process_state.ata_command_status = SATI_REASSIGN_BLOCKS_READY_TO_SEND; 221 return status; 222 } 223 224 /** 225 * @brief This method performs the retrieving of parameter LBA praparation and setting 226 * processing flags before/after calling SCSI Write sector command. 227 * @return Indicate if the method was successfully completed. 228 * @retval SATI_SUCCESS This is returned in all other cases. 229 */ 230 static 231 SATI_STATUS sati_reassign_blocks_write_condition( 232 SATI_TRANSLATOR_SEQUENCE_T * sequence, 233 void * scsi_io, 234 void * ata_io 235 ) 236 { 237 U8 current_lba_bytes[8] = {0,0,0,0,0,0,0,0}; 238 U32 lba_offset; 239 U8 page_size; 240 U32 index; 241 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 242 243 lba_offset = sequence->command_specific_data.reassign_blocks_process_state.lba_offset; 244 page_size = sequence->command_specific_data.reassign_blocks_process_state.lba_size; 245 246 for(index = 0; index < page_size; index++) 247 { 248 sati_get_data_byte(sequence, scsi_io, lba_offset+index, ¤t_lba_bytes[index]); 249 } 250 251 if (page_size == 4) 252 set_current_lba(current_lba_bytes, ata_io); 253 else 254 set_current_long_lba(current_lba_bytes, ata_io); 255 256 status = sati_reassign_blocks_write_command(sequence, scsi_io, ata_io); 257 sequence->command_specific_data.reassign_blocks_process_state.ata_command_sent_for_current_lba++; 258 sequence->command_specific_data.reassign_blocks_process_state.ata_command_status = SATI_REASSIGN_BLOCKS_READY_TO_SEND; 259 return status ; 260 } 261 262 263 /** 264 * @brief This method will perform the pre-processing of Reassign Blocks command and parameter. 265 */ 266 static 267 void sati_reassign_blocks_initial_processing( 268 SATI_TRANSLATOR_SEQUENCE_T * sequence, 269 void * scsi_io, 270 void * ata_io 271 ) 272 { 273 U32 index; 274 U8 long_lba_bit; 275 U8 long_list_bit; 276 U8 lba_offset; 277 U8 page_size; 278 U32 data_transfer_length; 279 U8 header_bytes[4]={0,0,0,0}; 280 281 U8 * cdb = sati_cb_get_cdb_address(scsi_io); 282 283 //A long LBA (LONGLBA) bit set to zero specifies that the REASSIGN BLOCKS defective LBA list contains four-byte LBAs. 284 //A LONGLBA bit set to one specifies that the REASSIGN BLOCKS defective LBA list contains eight-byte LBAs. 285 if ((sati_get_cdb_byte(cdb, 1) & SCSI_REASSIGN_BLOCKS_LONGLBA_BIT) == 0) 286 { 287 long_lba_bit=0; 288 page_size = 4; //beginning of lba list 289 } 290 else 291 { 292 long_lba_bit=1; 293 page_size = 8; 294 } 295 296 //The long list (LONGLIST) bit specifies which parameter list header 297 if ((sati_get_cdb_byte(cdb, 1) & SCSI_REASSIGN_BLOCKS_LONGLIST_BIT) == 0) 298 { 299 long_list_bit=0; 300 } 301 else 302 { 303 long_list_bit=1; 304 } 305 306 sequence->allocation_length = 4; //Pre-set allocation_length so that the header can be retrieved 307 308 //Get 4 bytes for headers (byte 2 & byte 3 for short header; long header all 4 bytes) 309 for(index = 0; index < 4; index++) 310 { 311 sati_get_data_byte(sequence, scsi_io, index, &header_bytes[index]); 312 } 313 314 lba_offset = 4; //beginning of lba list 315 316 if (long_list_bit==0) 317 { 318 //Header byte 2 and 3 is the parameter list length 319 data_transfer_length = (header_bytes[2]<<8) + header_bytes[3] + lba_offset; 320 } 321 else 322 { 323 //Header byte 0, 1, 2 and 3 contain the parameter list length 324 data_transfer_length = (header_bytes[0]<<24) + (header_bytes[1]<<16) + 325 (header_bytes[2]<<8) + header_bytes[3] + lba_offset; 326 } 327 328 sequence->allocation_length = data_transfer_length; 329 330 //Initialized the global processing state 331 sequence->command_specific_data.reassign_blocks_process_state.lba_size = page_size; 332 sequence->command_specific_data.reassign_blocks_process_state.lba_offset = lba_offset; 333 sequence->command_specific_data.reassign_blocks_process_state.ata_command_sent_for_current_lba = 0; 334 sequence->command_specific_data.reassign_blocks_process_state.block_lists_size = data_transfer_length - lba_offset; 335 sequence->command_specific_data.reassign_blocks_process_state.size_of_data_processed = 0; 336 sequence->command_specific_data.reassign_blocks_process_state.current_lba_processed = FALSE; 337 sequence->command_specific_data.reassign_blocks_process_state.ata_command_status = SATI_REASSIGN_BLOCKS_COMMAND_FAIL; 338 } 339 340 /** 341 * @brief This method will get the data size of not yet processed data. 342 * 343 * @param[in] lba_process_state This parameter points to the processing state fields 344 * of current block lba. 345 * 346 * @return This method returns the sizeof not yet processed data. 347 */ 348 static 349 U32 sati_reassign_blocks_unprocessed_data_size( 350 SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * lba_process_state 351 ) 352 { 353 U32 unprocessed_data_size; 354 355 if(lba_process_state->block_lists_size >= lba_process_state->size_of_data_processed) 356 { 357 unprocessed_data_size = lba_process_state->block_lists_size - 358 lba_process_state->size_of_data_processed; 359 } 360 else 361 { 362 unprocessed_data_size = 0; 363 } 364 365 return unprocessed_data_size; 366 } 367 368 369 /** 370 * @brief This method will check verify the sector and issue multiple ATA set feature commands to complete the translation. 371 * 372 * @param[in] reassign_blocks_process_state This parameter points to the processing state fields 373 * of current lba block. 374 * 375 * 376 * @return Indicate if the translation was successful. 377 * @retval SATI_SUCCESS 378 * @retval SATI_COMPLETE 379 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA 380 */ 381 static 382 SATI_STATUS sati_reassign_blocks_process_each_lba( 383 SATI_TRANSLATOR_SEQUENCE_T * sequence, 384 void * scsi_io, 385 void * ata_io 386 ) 387 { 388 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 389 SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state; 390 391 reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state; 392 393 if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 0)&& 394 (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_FAIL)) 395 { 396 reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size; 397 status = sati_reassign_blocks_verify_condition(sequence, scsi_io, ata_io); 398 } 399 else if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 0)&& 400 (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_SUCCESS)) 401 { 402 // point to next lba 403 reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size; 404 reassign_blocks_process_state->lba_offset += reassign_blocks_process_state->lba_size; 405 status = sati_reassign_blocks_verify_condition(sequence, scsi_io, ata_io); 406 } 407 else if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 1)&& 408 (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_FAIL)) 409 { 410 reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size; 411 status = sati_reassign_blocks_write_condition(sequence, scsi_io, ata_io); 412 } 413 else if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 2) && 414 (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_SUCCESS)) 415 { 416 reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size; 417 status = sati_reassign_blocks_verify_condition(sequence, scsi_io, ata_io); 418 } 419 else //commands sent is 2; SATI_REASSIGN_BLOCKS_COMMAND_FAIL 420 { 421 status = SATI_FAILURE_CHECK_RESPONSE_DATA; 422 } 423 424 return status; 425 } 426 427 /** 428 * @brief This method will process the each lba. 429 * 430 * @param[in] reassign_blocks_process_state This parameter points to the processing state fields 431 * of current lba. 432 * 433 * @return Indicate if the translation was successful. 434 * @retval SATI_SUCCESS 435 * @retval SATI_COMPLETE 436 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA 437 */ 438 static 439 SATI_STATUS sati_reassign_blocks_process( 440 SATI_TRANSLATOR_SEQUENCE_T * sequence, 441 void * scsi_io, 442 void * ata_io 443 ) 444 { 445 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 446 447 U32 page_size = 0; // in bytes 448 U32 size_of_data_to_be_processed; 449 U32 lba_offset; 450 SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state; 451 452 reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state; 453 454 lba_offset = reassign_blocks_process_state->lba_offset; 455 page_size = reassign_blocks_process_state->lba_size; 456 457 458 if(sati_reassign_blocks_unprocessed_data_size(reassign_blocks_process_state) < page_size) 459 { 460 return status; 461 } 462 463 // Any more lba blocks? If not, done. 464 if(reassign_blocks_process_state->block_lists_size == 465 reassign_blocks_process_state->size_of_data_processed) 466 { 467 sequence->state = SATI_SEQUENCE_STATE_FINAL; 468 status = SATI_COMPLETE; 469 } 470 //start processing next lba 471 else 472 { 473 size_of_data_to_be_processed = reassign_blocks_process_state->block_lists_size 474 - reassign_blocks_process_state->size_of_data_processed; 475 476 status = sati_reassign_blocks_process_each_lba(sequence, scsi_io, ata_io); 477 478 } 479 480 return status; 481 } 482 483 //****************************************************************************** 484 //* P U B L I C M E T H O D S 485 //****************************************************************************** 486 487 /** 488 * @brief This method will translate the SCSI Reassign Blocks command 489 * into corresponding ATA commands. Depending upon the capabilities 490 * supported by the target different ATA commands can be selected. 491 * Additionally, in some cases more than a single ATA command may 492 * be required. 493 * 494 * @return Indicate if the command translation succeeded. 495 * @retval SCI_SUCCESS This is returned if the command translation was 496 * successful. 497 * @retval SCI_COMPLETE This is returned if the command translation was 498 * successful and no ATA commands need to be set. 499 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if 500 * sense data has been created as a result of something specified 501 * in the parameter data fields. 502 */ 503 SATI_STATUS sati_reassign_blocks_translate_command( 504 SATI_TRANSLATOR_SEQUENCE_T * sequence, 505 void * scsi_io, 506 void * ata_io 507 ) 508 { 509 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 510 SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state; 511 512 reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state; 513 514 sequence->type = SATI_SEQUENCE_REASSIGN_BLOCKS; 515 516 //Initial processing if 517 if ( sequence->state != SATI_SEQUENCE_STATE_INCOMPLETE ) 518 { 519 sati_reassign_blocks_initial_processing( 520 sequence, 521 scsi_io, 522 ata_io 523 ); 524 } 525 526 // start processing current lba 527 if(reassign_blocks_process_state->current_lba_processed) 528 { 529 reassign_blocks_process_state->ata_command_sent_for_current_lba = 0; 530 reassign_blocks_process_state->current_lba_processed = FALSE; 531 } 532 533 status = sati_reassign_blocks_process(sequence, scsi_io, ata_io); 534 535 if(reassign_blocks_process_state->block_lists_size == 536 reassign_blocks_process_state->size_of_data_processed) 537 { 538 // Done this lba 539 sequence->state = SATI_SEQUENCE_STATE_FINAL; 540 } 541 else 542 { 543 sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE; 544 } 545 546 if(status == SATI_FAILURE_CHECK_RESPONSE_DATA) 547 { 548 sequence->state = SATI_SEQUENCE_STATE_FINAL; 549 sati_scsi_sense_data_construct( 550 sequence, 551 scsi_io, 552 SCSI_STATUS_CHECK_CONDITION, 553 SCSI_SENSE_MEDIUM_ERROR, 554 SCSI_ASC_UNRECOVERED_READ_ERROR, 555 SCSI_ASCQ_UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAIL 556 ); 557 } 558 559 return status; 560 } 561 562 /** 563 * @brief This method will translate the ATA command register FIS 564 * response into an appropriate SCSI response for Reassign Blocks 565 * For more information on the parameters passed to this method, 566 * please reference sati_translate_response(). 567 * 568 * @return Indicate if the response translation succeeded. 569 * @retval SCI_SUCCESS This is returned if the data translation was 570 * successful. 571 */ 572 SATI_STATUS sati_reassign_blocks_translate_response( 573 SATI_TRANSLATOR_SEQUENCE_T * sequence, 574 void * scsi_io, 575 void * ata_io 576 ) 577 { 578 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io); 579 SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state; 580 581 reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state; 582 583 if (sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT) 584 { 585 reassign_blocks_process_state->ata_command_status = SATI_REASSIGN_BLOCKS_COMMAND_FAIL; 586 587 //Checking for the number of ATA commands attempted on current LBA, stop 588 //the seaquence after 2 commands have returned errors. 589 if(reassign_blocks_process_state->ata_command_sent_for_current_lba < 2) 590 { 591 sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE; 592 reassign_blocks_process_state->size_of_data_processed -= reassign_blocks_process_state->lba_size; 593 return SATI_SEQUENCE_INCOMPLETE; 594 } 595 else 596 { 597 sati_scsi_sense_data_construct( 598 sequence, 599 scsi_io, 600 SCSI_STATUS_CHECK_CONDITION, 601 SCSI_SENSE_MEDIUM_ERROR, 602 SCSI_ASC_UNRECOVERED_READ_ERROR, 603 SCSI_ASCQ_UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAIL 604 ); 605 } 606 607 return SATI_FAILURE_CHECK_RESPONSE_DATA; 608 } 609 else 610 { 611 reassign_blocks_process_state->ata_command_status = SATI_REASSIGN_BLOCKS_COMMAND_SUCCESS; 612 if (reassign_blocks_process_state->ata_command_sent_for_current_lba != 2) 613 reassign_blocks_process_state->current_lba_processed = TRUE; 614 615 if (sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE) 616 { 617 return SATI_SEQUENCE_INCOMPLETE; 618 } 619 } 620 return SATI_COMPLETE; 621 } 622 623 #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS) 624 625