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 unmap command. 60 */ 61 62 #if !defined(DISABLE_SATI_UNMAP) 63 64 #include <dev/isci/scil/sati_unmap.h> 65 #include <dev/isci/scil/sati_callbacks.h> 66 #include <dev/isci/scil/sati_translator_sequence.h> 67 #include <dev/isci/scil/sati_util.h> 68 #include <dev/isci/scil/intel_ata.h> 69 #include <dev/isci/scil/intel_scsi.h> 70 #include <dev/isci/scil/intel_sat.h> 71 72 //****************************************************************************** 73 //* P R I V A T E M E T H O D S 74 //****************************************************************************** 75 76 /** 77 * @brief This method translates a given number of DSM 78 * requests into DSM blocks based on the devices logical block size 79 * 80 * @return Number of DSM blocks required for the DSM descriptor count 81 */ 82 U32 sati_unmap_calculate_dsm_blocks( 83 SATI_TRANSLATOR_SEQUENCE_T * sequence, 84 U32 dsm_descriptor_count 85 ) 86 { 87 U32 blocks = (dsm_descriptor_count * sizeof(TRIM_PAIR))/sequence->device->logical_block_size; 88 if ((dsm_descriptor_count * sizeof(TRIM_PAIR)) % sequence->device->logical_block_size) 89 { 90 blocks++; 91 } 92 return blocks; 93 } 94 95 /** 96 * @brief This method performs the SCSI Unmap command translation 97 * functionality. 98 * This includes: 99 * - setting the command register 100 * - setting the device head register 101 * - filling in fields in the SATI_TRANSLATOR_SEQUENCE object. 102 * For more information on the parameters passed to this method, 103 * please reference sati_translate_command(). 104 * 105 * @return Indicate if the method was successfully completed. 106 * @retval SATI_SUCCESS This is returned in all other cases. 107 */ 108 SATI_STATUS sati_unmap_construct( 109 SATI_TRANSLATOR_SEQUENCE_T * sequence, 110 void * scsi_io, 111 void * ata_io, 112 U32 sector_count 113 ) 114 { 115 U8 * h2d_register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 116 U8 * d2h_register_fis = sati_cb_get_d2h_register_fis_address(ata_io); 117 118 sati_set_ata_command(h2d_register_fis, ATA_DATA_SET_MANAGEMENT); 119 sati_set_ata_features(h2d_register_fis, 0x01); 120 sati_set_ata_sector_count(h2d_register_fis, (U8)sector_count); 121 sati_set_ata_device_head(h2d_register_fis, ATA_DEV_HEAD_REG_LBA_MODE_ENABLE); 122 123 // Set the completion status since the core will not do that for 124 // the udma fast path. 125 sati_set_ata_status(d2h_register_fis, 0x00); 126 127 // Set up the direction and protocol for SCIC 128 sequence->data_direction = SATI_DATA_DIRECTION_OUT; 129 sequence->protocol = SAT_PROTOCOL_UDMA_DATA_OUT; 130 // The UNMAP translation will always require a callback 131 // on every response so it can free memory if an error 132 // occurs. 133 sequence->is_translate_response_required = TRUE; 134 135 ASSERT(sector_count < 0x100); 136 137 return SATI_SUCCESS; 138 } 139 140 /** 141 * @brief This method updates the unmap sequence state to the next 142 * unmap descriptor 143 * 144 * @return Indicate if the method was successfully completed. 145 * @retval SATI_SUCCESS This is returned in all other cases. 146 */ 147 SATI_STATUS sati_unmap_load_next_descriptor( 148 SATI_TRANSLATOR_SEQUENCE_T * sequence, 149 void * scsi_io 150 ) 151 { 152 SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state; 153 U32 index; 154 U8 unmap_block_descriptor[16]; 155 156 unmap_process_state = &sequence->command_specific_data.unmap_process_state; 157 158 // Load the next descriptor 159 for(index = unmap_process_state->current_unmap_block_descriptor_index; 160 index < unmap_process_state->current_unmap_block_descriptor_index + 161 SATI_UNMAP_SIZEOF_SCSI_UNMAP_BLOCK_DESCRIPTOR; 162 index++) 163 { 164 sati_get_data_byte(sequence, 165 scsi_io, 166 index, 167 &unmap_block_descriptor[index-unmap_process_state->current_unmap_block_descriptor_index]); 168 } 169 170 // Update the internal state for the next translation pass 171 unmap_process_state->current_lba_count = (unmap_block_descriptor[8] << 24) | 172 (unmap_block_descriptor[9] << 16) | 173 (unmap_block_descriptor[10] << 8) | 174 (unmap_block_descriptor[11]); 175 unmap_process_state->current_lba = ((SATI_LBA)(unmap_block_descriptor[0]) << 56) | 176 ((SATI_LBA)(unmap_block_descriptor[1]) << 48) | 177 ((SATI_LBA)(unmap_block_descriptor[2]) << 40) | 178 ((SATI_LBA)(unmap_block_descriptor[3]) << 32) | 179 ((SATI_LBA)(unmap_block_descriptor[4]) << 24) | 180 ((SATI_LBA)(unmap_block_descriptor[5]) << 16) | 181 ((SATI_LBA)(unmap_block_descriptor[6]) << 8) | 182 ((SATI_LBA)(unmap_block_descriptor[7])); 183 unmap_process_state->next_lba = 0; 184 185 // Update the index for the next descriptor to translate 186 unmap_process_state->current_unmap_block_descriptor_index += SATI_UNMAP_SIZEOF_SCSI_UNMAP_BLOCK_DESCRIPTOR; 187 188 return SATI_SUCCESS; 189 } 190 191 /** 192 * @brief This method determines the max number of blocks of DSM data 193 * that can be satisfied by the device and the SW 194 * 195 * @return Number of blocks supported 196 * @retval Number of blocks supported 197 */ 198 U32 sati_unmap_get_max_buffer_size_in_blocks( 199 SATI_TRANSLATOR_SEQUENCE_T * sequence 200 ) 201 { 202 // Currently this SATI implementation only supports a single 203 // 4k block of memory for the DMA write operation for simplicity 204 // (no need to handle more than one SG element). 205 // Since most run time UNMAP requests use 1K or less buffer space, 206 // there is no performance degradation with only supporting a 207 // single physical page. For best results allocate the maximum 208 // amount of memory the device can handle up to the maximum of 4K. 209 return MIN(SATI_DSM_MAX_BUFFER_SIZE/sequence->device->logical_block_size, 210 sequence->device->max_lba_range_entry_blocks); 211 } 212 213 /** 214 * @brief This method will be called before starting the first unmap translation 215 * 216 * @return Indicate if the translation was successful. 217 * @retval SATI_SUCCESS This is returned if the command translation was 218 * successful and no further processing. 219 * @retval SATI_COMPLETE - The initial processing was completed successfully 220 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA - Failed the initial processing 221 */ 222 SATI_STATUS sati_unmap_initial_processing( 223 SATI_TRANSLATOR_SEQUENCE_T * sequence, 224 void * scsi_io, 225 void * ata_io 226 ) 227 { 228 SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state; 229 U8 * cdb; 230 U16 unmap_length; 231 U32 descriptor_length; 232 U32 index; 233 U32 max_dsm_blocks; 234 U8 unmap_param_list[8]; 235 236 unmap_process_state = &sequence->command_specific_data.unmap_process_state; 237 238 // Set up the sequence type for unmap translation 239 sequence->type = SATI_SEQUENCE_UNMAP; 240 241 // Make sure the device is TRIM capable 242 if ((sequence->device->capabilities & SATI_DEVICE_CAP_DSM_TRIM_SUPPORT) 243 != SATI_DEVICE_CAP_DSM_TRIM_SUPPORT) 244 { 245 // Can't send TRIM request to device that does not support it 246 sati_scsi_sense_data_construct( 247 sequence, 248 scsi_io, 249 SCSI_STATUS_CHECK_CONDITION, 250 SCSI_SENSE_ILLEGAL_REQUEST, 251 SCSI_ASC_INVALID_FIELD_IN_CDB, 252 SCSI_ASCQ_INVALID_FIELD_IN_CDB 253 ); 254 return SATI_FAILURE_CHECK_RESPONSE_DATA; 255 } 256 257 // get the amount of data being sent from the cdb 258 cdb = sati_cb_get_cdb_address(scsi_io); 259 unmap_length = (sati_get_cdb_byte(cdb, 7) << 8) | sati_get_cdb_byte(cdb, 8); 260 261 // If nothing has been requested return success now. 262 if (unmap_length == 0) 263 { 264 // SAT: This is not an error 265 return SATI_SUCCESS; 266 } 267 if (unmap_length < SATI_UNMAP_SIZEOF_SCSI_UNMAP_PARAMETER_LIST) 268 { 269 // Not enough length specified in the CDB 270 sati_scsi_sense_data_construct( 271 sequence, 272 scsi_io, 273 SCSI_STATUS_CHECK_CONDITION, 274 SCSI_SENSE_ILLEGAL_REQUEST, 275 SCSI_ASC_INVALID_FIELD_IN_CDB, 276 SCSI_ASCQ_INVALID_FIELD_IN_CDB 277 ); 278 return SATI_FAILURE_CHECK_RESPONSE_DATA; 279 } 280 281 sequence->allocation_length = unmap_length; 282 283 // Get the unmap parameter header 284 for(index = 0; index < SATI_UNMAP_SIZEOF_SCSI_UNMAP_PARAMETER_LIST; index++) 285 { 286 sati_get_data_byte(sequence, scsi_io, index, &unmap_param_list[index]); 287 } 288 descriptor_length = (unmap_param_list[2] << 8) | unmap_param_list[3]; 289 290 // Check length again 291 if (descriptor_length == 0) 292 { 293 // SAT: This is not an error 294 return SATI_SUCCESS; 295 } 296 297 if ((U32)(unmap_length - SATI_UNMAP_SIZEOF_SCSI_UNMAP_PARAMETER_LIST) < descriptor_length) 298 { 299 // Not enough length specified in the CDB 300 sati_scsi_sense_data_construct( 301 sequence, 302 scsi_io, 303 SCSI_STATUS_CHECK_CONDITION, 304 SCSI_SENSE_ILLEGAL_REQUEST, 305 SCSI_ASC_INVALID_FIELD_IN_CDB, 306 SCSI_ASCQ_INVALID_FIELD_IN_CDB 307 ); 308 return SATI_FAILURE_CHECK_RESPONSE_DATA; 309 } 310 311 // Save the maximum unmap block descriptors in this request 312 unmap_process_state->max_unmap_block_descriptors = 313 descriptor_length/SATI_UNMAP_SIZEOF_SCSI_UNMAP_BLOCK_DESCRIPTOR; 314 315 // Determine the maximum size of the write buffer that will be required 316 // for the translation in terms of number of blocks 317 max_dsm_blocks = sati_unmap_get_max_buffer_size_in_blocks(sequence); 318 319 // Save the maximum number of DSM descriptors we can send during the translation 320 unmap_process_state->max_lba_range_entries = 321 (max_dsm_blocks*sequence->device->logical_block_size)/sizeof(TRIM_PAIR); 322 323 // Get the write buffer for the translation 324 sati_cb_allocate_dma_buffer( 325 scsi_io, 326 max_dsm_blocks*sequence->device->logical_block_size, 327 &(unmap_process_state->virtual_unmap_buffer), 328 &(unmap_process_state->physical_unmap_buffer_low), 329 &(unmap_process_state->physical_unmap_buffer_high)); 330 331 // Makes sure we have a buffer 332 if (unmap_process_state->virtual_unmap_buffer == NULL) 333 { 334 // Resource failure 335 sati_scsi_sense_data_construct( 336 sequence, 337 scsi_io, 338 SCSI_STATUS_BUSY, 339 SCSI_SENSE_NO_SENSE, 340 SCSI_ASC_NO_ADDITIONAL_SENSE, 341 SCSI_ASCQ_NO_ADDITIONAL_SENSE 342 ); 343 return SATI_FAILURE_CHECK_RESPONSE_DATA; 344 } 345 346 // Get the first SGL entry. This code will only use one 4K page so will 347 // only utilize the first sge. 348 sati_cb_sgl_next_sge(scsi_io, 349 ata_io, 350 NULL, 351 &(unmap_process_state->unmap_buffer_sgl_pair)); 352 353 // Load the first descriptor to start the translation loop 354 unmap_process_state->current_unmap_block_descriptor_index = 355 SATI_UNMAP_SIZEOF_SCSI_UNMAP_PARAMETER_LIST; 356 sati_unmap_load_next_descriptor(sequence,scsi_io); 357 358 // Next state will be incomplete since translation 359 // will require a callback and possibly more requests. 360 sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE; 361 362 return SATI_COMPLETE; 363 } 364 365 /** 366 * @brief This method will process each unmap sequence. 367 * 368 * @return Indicate if the translation was successful. 369 * @retval SATI_SUCCESS 370 */ 371 SATI_STATUS sati_unmap_process( 372 SATI_TRANSLATOR_SEQUENCE_T * sequence, 373 void * scsi_io, 374 void * ata_io 375 ) 376 { 377 SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state; 378 SATI_LBA dsm_descriptor_lba_count; 379 U32 dsm_descriptor; 380 U32 dsm_bytes; 381 U32 dsm_remainder_bytes; 382 U32 dsm_blocks; 383 U32 max_dsm_blocks; 384 385 unmap_process_state = &sequence->command_specific_data.unmap_process_state; 386 387 // Set up the starting address of the buffer for this portion of the translation 388 unmap_process_state->current_dsm_descriptor = unmap_process_state->virtual_unmap_buffer; 389 dsm_descriptor = 0; 390 391 // Translate as much as we can 392 while ((dsm_descriptor < unmap_process_state->max_lba_range_entries) && 393 (unmap_process_state->current_lba_count > 0)) { 394 // See if the LBA count will fit in to a single descriptor 395 if (unmap_process_state->current_lba_count > SATI_DSM_MAX_SECTOR_COUNT) { 396 // Can't fit all of the lbas for this descriptor in to 397 // one DSM request. Adjust the current LbaCount and total 398 // remaining for the next descriptor 399 dsm_descriptor_lba_count = SATI_DSM_MAX_SECTOR_COUNT; 400 unmap_process_state->current_lba_count -= SATI_DSM_MAX_SECTOR_COUNT; 401 unmap_process_state->next_lba = 402 unmap_process_state->current_lba + SATI_DSM_MAX_SECTOR_COUNT; 403 } else { 404 // It all fits in to one descriptor 405 dsm_descriptor_lba_count = unmap_process_state->current_lba_count; 406 unmap_process_state->current_lba_count = 0; 407 } 408 409 // Fill in the ATA DSM descriptor 410 ((PTRIM_PAIR)(unmap_process_state->current_dsm_descriptor))->sector_address = 411 unmap_process_state->current_lba; 412 ((PTRIM_PAIR)(unmap_process_state->current_dsm_descriptor))->sector_count = 413 dsm_descriptor_lba_count; 414 415 // See if we can move on to the next descriptor 416 if (unmap_process_state->current_lba_count == 0) { 417 // See if there is another descriptor 418 --unmap_process_state->max_unmap_block_descriptors; 419 if (unmap_process_state->max_unmap_block_descriptors > 0) { 420 // Move on to the next descriptor 421 sati_unmap_load_next_descriptor(sequence,scsi_io); 422 } 423 } else { 424 // Move to the next LBA in this descriptor 425 unmap_process_state->current_lba = unmap_process_state->next_lba; 426 } 427 428 // Make sure the LBA does not exceed 48 bits... 429 ASSERT(unmap_process_state->current_lba <= SATI_DSM_MAX_SECTOR_ADDRESS); 430 431 // Increment the number of descriptors used and point to the next entry 432 dsm_descriptor++; 433 unmap_process_state->current_dsm_descriptor = 434 (U8 *)(unmap_process_state->current_dsm_descriptor) + sizeof(TRIM_PAIR); 435 } 436 437 // Calculate number of blocks we have filled in 438 dsm_blocks = sati_unmap_calculate_dsm_blocks(sequence,dsm_descriptor); 439 dsm_bytes = dsm_blocks * sequence->device->logical_block_size; 440 max_dsm_blocks = sati_unmap_get_max_buffer_size_in_blocks(sequence); 441 442 // The current_dsm_descriptor points to the next location in the buffer 443 // Get the remaining bytes from the last translated descriptor 444 // to the end of the 4k buffer. 445 dsm_remainder_bytes = sequence->device->logical_block_size; 446 dsm_remainder_bytes -= (U32)((POINTER_UINT)unmap_process_state->current_dsm_descriptor & 447 (sequence->device->logical_block_size-1)); 448 449 // If there was no remainder, the complete buffer was filled in. 450 if (dsm_remainder_bytes != sequence->device->logical_block_size) 451 { 452 // Add on the remaining unfilled blocks 453 dsm_remainder_bytes += (sequence->device->logical_block_size * (max_dsm_blocks - dsm_blocks)); 454 455 // According to ATA-8, if the DSM buffer is not completely filled with 456 // valid DSM descriptor data, the remaining portion of the 457 // buffer must be filled in with zeros. 458 memset((U8 *)unmap_process_state->current_dsm_descriptor, 0, dsm_remainder_bytes); 459 } 460 461 // Tell scic to utilize this sgl pair for write DMA processing of 462 // the SCSI UNMAP translation with the total number of bytes for this transfer 463 sati_cb_sge_write(unmap_process_state->unmap_buffer_sgl_pair, 464 unmap_process_state->physical_unmap_buffer_low, 465 unmap_process_state->physical_unmap_buffer_high, 466 dsm_bytes); 467 468 // Construct the unmap ATA request 469 sati_unmap_construct(sequence, 470 scsi_io, 471 ata_io, 472 dsm_blocks); 473 474 // Determine sequence next state based on whether there is more translation 475 // to complete 476 if (unmap_process_state->current_lba_count == 0) 477 { 478 // used for completion routine to determine if there is more processing 479 sequence->state = SATI_SEQUENCE_STATE_FINAL; 480 } 481 // This requests has already translated the SGL, have SCIC skip SGL translataion 482 return SATI_SUCCESS_SGL_TRANSLATED; 483 } 484 485 //****************************************************************************** 486 //* P U B L I C M E T H O D S 487 //****************************************************************************** 488 489 /** 490 * @brief This method will handle termination of the 491 * SCSI unmap translation and frees previously allocated 492 * dma buffer. 493 * 494 * @return None 495 */ 496 void sati_unmap_terminate( 497 SATI_TRANSLATOR_SEQUENCE_T * sequence, 498 void * scsi_io, 499 void * ata_io 500 ) 501 { 502 SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state; 503 unmap_process_state = &sequence->command_specific_data.unmap_process_state; 504 505 if (unmap_process_state->virtual_unmap_buffer != NULL) 506 { 507 sati_cb_free_dma_buffer(scsi_io, unmap_process_state->virtual_unmap_buffer); 508 unmap_process_state->virtual_unmap_buffer = NULL; 509 } 510 } 511 512 /** 513 * @brief This method will translate the SCSI Unmap command 514 * into corresponding ATA commands. Depending upon the capabilities 515 * supported by the target different ATA commands can be selected. 516 * Additionally, in some cases more than a single ATA command may 517 * be required. 518 * 519 * @return Indicate if the command translation succeeded. 520 * @retval SATI_SUCCESS This is returned if the command translation was 521 * successful. 522 * @retval SATI_COMPLETE This is returned if the command translation was 523 * successful and no ATA commands need to be set. 524 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if 525 * sense data has been created as a result of something specified 526 * in the parameter data fields. 527 */ 528 SATI_STATUS sati_unmap_translate_command( 529 SATI_TRANSLATOR_SEQUENCE_T * sequence, 530 void * scsi_io, 531 void * ata_io 532 ) 533 { 534 SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 535 SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state; 536 537 unmap_process_state = &sequence->command_specific_data.unmap_process_state; 538 539 // Determine if this is the first step in the unmap sequence 540 if ( sequence->state == SATI_SEQUENCE_STATE_INITIAL ) 541 { 542 status = sati_unmap_initial_processing(sequence,scsi_io,ata_io); 543 if (status != SATI_COMPLETE) 544 { 545 return status; 546 } 547 } 548 // Translate the next portion of the UNMAP request 549 return sati_unmap_process(sequence, scsi_io, ata_io); 550 } 551 552 /** 553 * @brief This method will translate the ATA command register FIS 554 * response into an appropriate SCSI response for Unmap. 555 * For more information on the parameters passed to this method, 556 * please reference sati_translate_response(). 557 * 558 * @return Indicate if the response translation succeeded. 559 * @retval SATI_SUCCESS This is returned if the command translation was 560 * successful. 561 * @retval SATI_COMPLETE This is returned if the command translation was 562 * successful and no ATA commands need to be set. 563 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if 564 * sense data has been created as a result of something specified 565 * in the parameter data fields. 566 */ 567 SATI_STATUS sati_unmap_translate_response( 568 SATI_TRANSLATOR_SEQUENCE_T * sequence, 569 void * scsi_io, 570 void * ata_io 571 ) 572 { 573 U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io); 574 SATI_UNMAP_PROCESSING_STATE_T * unmap_process_state; 575 SATI_STATUS sati_status = SATI_COMPLETE; 576 577 unmap_process_state = &sequence->command_specific_data.unmap_process_state; 578 579 if (sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT) 580 { 581 sequence->state = SATI_SEQUENCE_STATE_FINAL; 582 sati_scsi_sense_data_construct( 583 sequence, 584 scsi_io, 585 SCSI_STATUS_CHECK_CONDITION, 586 SCSI_SENSE_ABORTED_COMMAND, 587 SCSI_ASC_NO_ADDITIONAL_SENSE, 588 SCSI_ASCQ_NO_ADDITIONAL_SENSE 589 ); 590 // All done, terminate the translation 591 sati_unmap_terminate(sequence, scsi_io, ata_io); 592 } 593 else 594 { 595 if (sequence->state != SATI_SEQUENCE_STATE_INCOMPLETE) 596 { 597 // All done, terminate the translation 598 sati_unmap_terminate(sequence, scsi_io, ata_io); 599 } 600 else 601 { 602 // Still translating 603 sati_status = SATI_SEQUENCE_STATE_INCOMPLETE; 604 } 605 } 606 return sati_status; 607 } 608 609 #endif // !defined(DISABLE_SATI_UNMAP) 610