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 /** 57 * @file 58 * @brief This file contains the method implementations required to 59 * translate the SCSI reassign blocks command. 60 */ 61 62 #if !defined(DISABLE_SATI_REASSIGN_BLOCKS) 63 64 #include <dev/isci/scil/sati_reassign_blocks.h> 65 #include <dev/isci/scil/sati_callbacks.h> 66 #include <dev/isci/scil/sati_move.h> 67 #include <dev/isci/scil/sati_write.h> 68 #include <dev/isci/scil/sati_translator_sequence.h> 69 #include <dev/isci/scil/sati_util.h> 70 #include <dev/isci/scil/intel_scsi.h> 71 72 73 //****************************************************************************** 74 //* P R I V A T E M E T H O D S 75 //****************************************************************************** 76 // static SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T reassign_blocks_processing_state; 77 78 /** 79 * @brief This method copies short 24bits LBA bytes to the command register 80 * @return Indicate if the method was successfully completed. 81 * @retval SATI_SUCCESS This is returned in all other cases. 82 */ 83 static 84 void set_current_lba(U8 * lba, void * ata_io) 85 { 86 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 87 88 sati_set_ata_lba_low(register_fis, lba[0]); 89 sati_set_ata_lba_mid(register_fis, lba[1]); 90 sati_set_ata_lba_high(register_fis, lba[2]); 91 sati_set_ata_device_head(register_fis, ATA_DEV_HEAD_REG_LBA_MODE_ENABLE | (lba[3] & 0x0F)); 92 93 94 } 95 96 /** 97 * @brief This method copies short 48bits LBA bytes to the command register 98 * @return Indicate if the method was successfully completed. 99 * @retval SATI_SUCCESS This is returned in all other cases. 100 */ 101 static 102 void set_current_long_lba(U8 * lba, void * ata_io) 103 { 104 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 105 106 sati_set_ata_lba_low(register_fis, lba[0]); 107 sati_set_ata_lba_mid(register_fis, lba[1]); 108 sati_set_ata_lba_high(register_fis, lba[2]); 109 sati_set_ata_lba_low_exp(register_fis, lba[3]); 110 sati_set_ata_lba_mid_exp(register_fis, lba[4]); 111 sati_set_ata_lba_high_exp(register_fis, lba[5]); 112 } 113 114 /** 115 * @brief This method performs the SCSI VERIFY command translation 116 * functionality. 117 * This includes: 118 * - setting the command register 119 * - setting the device head register 120 * - filling in fields in the SATI_TRANSLATOR_SEQUENCE object. 121 * For more information on the parameters passed to this method, 122 * please reference sati_translate_command(). 123 * 124 * @return Indicate if the method was successfully completed. 125 * @retval SATI_SUCCESS This is returned in all other cases. 126 */ 127 static 128 SATI_STATUS sati_reassign_blocks_verify_command( 129 SATI_TRANSLATOR_SEQUENCE_T * sequence, 130 void * scsi_io, 131 void * ata_io 132 ) 133 { 134 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 135 136 sati_ata_non_data_command(ata_io, sequence); 137 138 // Ensure the device supports the 48 bit feature set. 139 if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE) 140 sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS_EXT); 141 else 142 sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS); 143 144 return SATI_SUCCESS; 145 } 146 147 /** 148 * @brief This method performs the SCSI Write sector command translation 149 * functionality. 150 * This includes: 151 * - setting the command register 152 * - setting the device head register 153 * - filling in fields in the SATI_TRANSLATOR_SEQUENCE object. 154 * For more information on the parameters passed to this method, 155 * please reference sati_translate_command(). 156 * 157 * @return Indicate if the method was successfully completed. 158 * @retval SATI_SUCCESS This is returned in all other cases. 159 */ 160 static 161 SATI_STATUS sati_reassign_blocks_write_command( 162 SATI_TRANSLATOR_SEQUENCE_T * sequence, 163 void * scsi_io, 164 void * ata_io 165 ) 166 { 167 U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 168 169 sati_ata_non_data_command(ata_io, sequence); 170 sequence->data_direction = SATI_DATA_DIRECTION_OUT; 171 172 // sati_set_ata_sector_count(register_fis, 1); 173 // status=sati_move_set_sector_count(sequence,scsi_io,ata_io,1,0); 174 175 // Ensure the device supports the 48 bit feature set. 176 if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE) 177 sati_set_ata_command(register_fis, ATA_WRITE_DMA_EXT); 178 else 179 sati_set_ata_command(register_fis, ATA_WRITE_DMA); 180 181 return SATI_SUCCESS; //sati_move_set_sector_count(sequence,scsi_io,ata_io,1,0); 182 } 183 184 /** 185 * @brief This method performs the retrieving of parameter LBA praparation and setting 186 * processing flags before/after calling SCSI Verify sector command. 187 * @return Indicate if the method was successfully completed. 188 * @retval SATI_SUCCESS This is returned in all other cases. 189 */ 190 static 191 SATI_STATUS sati_reassign_blocks_verify_condition( 192 SATI_TRANSLATOR_SEQUENCE_T * sequence, 193 void * scsi_io, 194 void * ata_io 195 ) 196 { 197 U8 current_lba_bytes[8] = {0,0,0,0,0,0,0,0}; 198 U32 lba_offset; 199 U8 page_size; 200 U32 index; 201 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 202 203 lba_offset = sequence->command_specific_data.reassign_blocks_process_state.lba_offset; 204 page_size = sequence->command_specific_data.reassign_blocks_process_state.lba_size; 205 206 for(index = 0; index < page_size; index++) 207 { 208 sati_get_data_byte(sequence, scsi_io, lba_offset+index, ¤t_lba_bytes[index]); 209 } 210 211 if (page_size == 4) 212 set_current_lba(current_lba_bytes, ata_io); 213 else 214 set_current_long_lba(current_lba_bytes, ata_io); 215 216 status = sati_reassign_blocks_verify_command(sequence, scsi_io, ata_io); 217 sequence->command_specific_data.reassign_blocks_process_state.ata_command_sent_for_current_lba++; 218 sequence->command_specific_data.reassign_blocks_process_state.ata_command_status = SATI_REASSIGN_BLOCKS_READY_TO_SEND; 219 return status; 220 } 221 222 /** 223 * @brief This method performs the retrieving of parameter LBA praparation and setting 224 * processing flags before/after calling SCSI Write sector command. 225 * @return Indicate if the method was successfully completed. 226 * @retval SATI_SUCCESS This is returned in all other cases. 227 */ 228 static 229 SATI_STATUS sati_reassign_blocks_write_condition( 230 SATI_TRANSLATOR_SEQUENCE_T * sequence, 231 void * scsi_io, 232 void * ata_io 233 ) 234 { 235 U8 current_lba_bytes[8] = {0,0,0,0,0,0,0,0}; 236 U32 lba_offset; 237 U8 page_size; 238 U32 index; 239 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 240 241 lba_offset = sequence->command_specific_data.reassign_blocks_process_state.lba_offset; 242 page_size = sequence->command_specific_data.reassign_blocks_process_state.lba_size; 243 244 for(index = 0; index < page_size; index++) 245 { 246 sati_get_data_byte(sequence, scsi_io, lba_offset+index, ¤t_lba_bytes[index]); 247 } 248 249 if (page_size == 4) 250 set_current_lba(current_lba_bytes, ata_io); 251 else 252 set_current_long_lba(current_lba_bytes, ata_io); 253 254 status = sati_reassign_blocks_write_command(sequence, scsi_io, ata_io); 255 sequence->command_specific_data.reassign_blocks_process_state.ata_command_sent_for_current_lba++; 256 sequence->command_specific_data.reassign_blocks_process_state.ata_command_status = SATI_REASSIGN_BLOCKS_READY_TO_SEND; 257 return status ; 258 } 259 260 261 /** 262 * @brief This method will perform the pre-processing of Reassign Blocks command and parameter. 263 */ 264 static 265 void sati_reassign_blocks_initial_processing( 266 SATI_TRANSLATOR_SEQUENCE_T * sequence, 267 void * scsi_io, 268 void * ata_io 269 ) 270 { 271 U32 index; 272 U8 long_lba_bit; 273 U8 long_list_bit; 274 U8 lba_offset; 275 U8 page_size; 276 U32 data_transfer_length; 277 U8 header_bytes[4]={0,0,0,0}; 278 279 U8 * cdb = sati_cb_get_cdb_address(scsi_io); 280 281 //A long LBA (LONGLBA) bit set to zero specifies that the REASSIGN BLOCKS defective LBA list contains four-byte LBAs. 282 //A LONGLBA bit set to one specifies that the REASSIGN BLOCKS defective LBA list contains eight-byte LBAs. 283 if ((sati_get_cdb_byte(cdb, 1) & SCSI_REASSIGN_BLOCKS_LONGLBA_BIT) == 0) 284 { 285 long_lba_bit=0; 286 page_size = 4; //beginning of lba list 287 } 288 else 289 { 290 long_lba_bit=1; 291 page_size = 8; 292 } 293 294 //The long list (LONGLIST) bit specifies which parameter list header 295 if ((sati_get_cdb_byte(cdb, 1) & SCSI_REASSIGN_BLOCKS_LONGLIST_BIT) == 0) 296 { 297 long_list_bit=0; 298 } 299 else 300 { 301 long_list_bit=1; 302 } 303 304 sequence->allocation_length = 4; //Pre-set allocation_length so that the header can be retrieved 305 306 //Get 4 bytes for headers (byte 2 & byte 3 for short header; long header all 4 bytes) 307 for(index = 0; index < 4; index++) 308 { 309 sati_get_data_byte(sequence, scsi_io, index, &header_bytes[index]); 310 } 311 312 lba_offset = 4; //beginning of lba list 313 314 if (long_list_bit==0) 315 { 316 //Header byte 2 and 3 is the parameter list length 317 data_transfer_length = (header_bytes[2]<<8) + header_bytes[3] + lba_offset; 318 } 319 else 320 { 321 //Header byte 0, 1, 2 and 3 contain the parameter list length 322 data_transfer_length = (header_bytes[0]<<24) + (header_bytes[1]<<16) + 323 (header_bytes[2]<<8) + header_bytes[3] + lba_offset; 324 } 325 326 sequence->allocation_length = data_transfer_length; 327 328 //Initialized the global processing state 329 sequence->command_specific_data.reassign_blocks_process_state.lba_size = page_size; 330 sequence->command_specific_data.reassign_blocks_process_state.lba_offset = lba_offset; 331 sequence->command_specific_data.reassign_blocks_process_state.ata_command_sent_for_current_lba = 0; 332 sequence->command_specific_data.reassign_blocks_process_state.block_lists_size = data_transfer_length - lba_offset; 333 sequence->command_specific_data.reassign_blocks_process_state.size_of_data_processed = 0; 334 sequence->command_specific_data.reassign_blocks_process_state.current_lba_processed = FALSE; 335 sequence->command_specific_data.reassign_blocks_process_state.ata_command_status = SATI_REASSIGN_BLOCKS_COMMAND_FAIL; 336 } 337 338 /** 339 * @brief This method will get the data size of not yet processed data. 340 * 341 * @param[in] lba_process_state This parameter points to the processing state fields 342 * of current block lba. 343 * 344 * @return This method returns the sizeof not yet processed data. 345 */ 346 static 347 U32 sati_reassign_blocks_unprocessed_data_size( 348 SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * lba_process_state 349 ) 350 { 351 U32 unprocessed_data_size; 352 353 if(lba_process_state->block_lists_size >= lba_process_state->size_of_data_processed) 354 { 355 unprocessed_data_size = lba_process_state->block_lists_size - 356 lba_process_state->size_of_data_processed; 357 } 358 else 359 { 360 unprocessed_data_size = 0; 361 } 362 363 return unprocessed_data_size; 364 } 365 366 367 /** 368 * @brief This method will check verify the sector and issue multiple ATA set feature commands to complete the translation. 369 * 370 * @param[in] reassign_blocks_process_state This parameter points to the processing state fields 371 * of current lba block. 372 * 373 * 374 * @return Indicate if the translation was successful. 375 * @retval SATI_SUCCESS 376 * @retval SATI_COMPLETE 377 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA 378 */ 379 static 380 SATI_STATUS sati_reassign_blocks_process_each_lba( 381 SATI_TRANSLATOR_SEQUENCE_T * sequence, 382 void * scsi_io, 383 void * ata_io 384 ) 385 { 386 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 387 SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state; 388 389 reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state; 390 391 if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 0)&& 392 (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_FAIL)) 393 { 394 reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size; 395 status = sati_reassign_blocks_verify_condition(sequence, scsi_io, ata_io); 396 } 397 else if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 0)&& 398 (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_SUCCESS)) 399 { 400 // point to next lba 401 reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size; 402 reassign_blocks_process_state->lba_offset += reassign_blocks_process_state->lba_size; 403 status = sati_reassign_blocks_verify_condition(sequence, scsi_io, ata_io); 404 } 405 else if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 1)&& 406 (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_FAIL)) 407 { 408 reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size; 409 status = sati_reassign_blocks_write_condition(sequence, scsi_io, ata_io); 410 } 411 else if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 2) && 412 (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_SUCCESS)) 413 { 414 reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size; 415 status = sati_reassign_blocks_verify_condition(sequence, scsi_io, ata_io); 416 } 417 else //commands sent is 2; SATI_REASSIGN_BLOCKS_COMMAND_FAIL 418 { 419 status = SATI_FAILURE_CHECK_RESPONSE_DATA; 420 } 421 422 return status; 423 } 424 425 /** 426 * @brief This method will process the each lba. 427 * 428 * @param[in] reassign_blocks_process_state This parameter points to the processing state fields 429 * of current lba. 430 * 431 * @return Indicate if the translation was successful. 432 * @retval SATI_SUCCESS 433 * @retval SATI_COMPLETE 434 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA 435 */ 436 static 437 SATI_STATUS sati_reassign_blocks_process( 438 SATI_TRANSLATOR_SEQUENCE_T * sequence, 439 void * scsi_io, 440 void * ata_io 441 ) 442 { 443 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 444 445 U32 page_size = 0; // in bytes 446 U32 size_of_data_to_be_processed; 447 U32 lba_offset; 448 SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state; 449 450 reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state; 451 452 lba_offset = reassign_blocks_process_state->lba_offset; 453 page_size = reassign_blocks_process_state->lba_size; 454 455 456 if(sati_reassign_blocks_unprocessed_data_size(reassign_blocks_process_state) < page_size) 457 { 458 return status; 459 } 460 461 // Any more lba blocks? If not, done. 462 if(reassign_blocks_process_state->block_lists_size == 463 reassign_blocks_process_state->size_of_data_processed) 464 { 465 sequence->state = SATI_SEQUENCE_STATE_FINAL; 466 status = SATI_COMPLETE; 467 } 468 //start processing next lba 469 else 470 { 471 size_of_data_to_be_processed = reassign_blocks_process_state->block_lists_size 472 - reassign_blocks_process_state->size_of_data_processed; 473 474 status = sati_reassign_blocks_process_each_lba(sequence, scsi_io, ata_io); 475 476 } 477 478 return status; 479 } 480 481 //****************************************************************************** 482 //* P U B L I C M E T H O D S 483 //****************************************************************************** 484 485 /** 486 * @brief This method will translate the SCSI Reassign Blocks command 487 * into corresponding ATA commands. Depending upon the capabilities 488 * supported by the target different ATA commands can be selected. 489 * Additionally, in some cases more than a single ATA command may 490 * be required. 491 * 492 * @return Indicate if the command translation succeeded. 493 * @retval SCI_SUCCESS This is returned if the command translation was 494 * successful. 495 * @retval SCI_COMPLETE This is returned if the command translation was 496 * successful and no ATA commands need to be set. 497 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if 498 * sense data has been created as a result of something specified 499 * in the parameter data fields. 500 */ 501 SATI_STATUS sati_reassign_blocks_translate_command( 502 SATI_TRANSLATOR_SEQUENCE_T * sequence, 503 void * scsi_io, 504 void * ata_io 505 ) 506 { 507 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 508 SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state; 509 510 reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state; 511 512 sequence->type = SATI_SEQUENCE_REASSIGN_BLOCKS; 513 514 //Initial processing if 515 if ( sequence->state != SATI_SEQUENCE_STATE_INCOMPLETE ) 516 { 517 sati_reassign_blocks_initial_processing( 518 sequence, 519 scsi_io, 520 ata_io 521 ); 522 } 523 524 // start processing current lba 525 if(reassign_blocks_process_state->current_lba_processed) 526 { 527 reassign_blocks_process_state->ata_command_sent_for_current_lba = 0; 528 reassign_blocks_process_state->current_lba_processed = FALSE; 529 } 530 531 status = sati_reassign_blocks_process(sequence, scsi_io, ata_io); 532 533 if(reassign_blocks_process_state->block_lists_size == 534 reassign_blocks_process_state->size_of_data_processed) 535 { 536 // Done this lba 537 sequence->state = SATI_SEQUENCE_STATE_FINAL; 538 } 539 else 540 { 541 sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE; 542 } 543 544 if(status == SATI_FAILURE_CHECK_RESPONSE_DATA) 545 { 546 sequence->state = SATI_SEQUENCE_STATE_FINAL; 547 sati_scsi_sense_data_construct( 548 sequence, 549 scsi_io, 550 SCSI_STATUS_CHECK_CONDITION, 551 SCSI_SENSE_MEDIUM_ERROR, 552 SCSI_ASC_UNRECOVERED_READ_ERROR, 553 SCSI_ASCQ_UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAIL 554 ); 555 } 556 557 return status; 558 } 559 560 /** 561 * @brief This method will translate the ATA command register FIS 562 * response into an appropriate SCSI response for Reassign Blocks 563 * For more information on the parameters passed to this method, 564 * please reference sati_translate_response(). 565 * 566 * @return Indicate if the response translation succeeded. 567 * @retval SCI_SUCCESS This is returned if the data translation was 568 * successful. 569 */ 570 SATI_STATUS sati_reassign_blocks_translate_response( 571 SATI_TRANSLATOR_SEQUENCE_T * sequence, 572 void * scsi_io, 573 void * ata_io 574 ) 575 { 576 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io); 577 SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state; 578 579 reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state; 580 581 if (sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT) 582 { 583 reassign_blocks_process_state->ata_command_status = SATI_REASSIGN_BLOCKS_COMMAND_FAIL; 584 585 //Checking for the number of ATA commands attempted on current LBA, stop 586 //the seaquence after 2 commands have returned errors. 587 if(reassign_blocks_process_state->ata_command_sent_for_current_lba < 2) 588 { 589 sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE; 590 reassign_blocks_process_state->size_of_data_processed -= reassign_blocks_process_state->lba_size; 591 return SATI_SEQUENCE_INCOMPLETE; 592 } 593 else 594 { 595 sati_scsi_sense_data_construct( 596 sequence, 597 scsi_io, 598 SCSI_STATUS_CHECK_CONDITION, 599 SCSI_SENSE_MEDIUM_ERROR, 600 SCSI_ASC_UNRECOVERED_READ_ERROR, 601 SCSI_ASCQ_UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAIL 602 ); 603 } 604 605 return SATI_FAILURE_CHECK_RESPONSE_DATA; 606 } 607 else 608 { 609 reassign_blocks_process_state->ata_command_status = SATI_REASSIGN_BLOCKS_COMMAND_SUCCESS; 610 if (reassign_blocks_process_state->ata_command_sent_for_current_lba != 2) 611 reassign_blocks_process_state->current_lba_processed = TRUE; 612 613 if (sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE) 614 { 615 return SATI_SEQUENCE_INCOMPLETE; 616 } 617 } 618 return SATI_COMPLETE; 619 } 620 621 #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS) 622 623