1 /*- 2 * This file is provided under a dual BSD/GPLv2 license. When using or 3 * redistributing this file, you may do so under either license. 4 * 5 * GPL LICENSE SUMMARY 6 * 7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of version 2 of the GNU General Public License as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21 * The full GNU General Public License is included in this distribution 22 * in the file called LICENSE.GPL. 23 * 24 * BSD LICENSE 25 * 26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27 * All rights reserved. 28 * 29 * Redistribution and use in source and binary forms, with or without 30 * modification, are permitted provided that the following conditions 31 * are met: 32 * 33 * * Redistributions of source code must retain the above copyright 34 * notice, this list of conditions and the following disclaimer. 35 * * Redistributions in binary form must reproduce the above copyright 36 * notice, this list of conditions and the following disclaimer in 37 * the documentation and/or other materials provided with the 38 * distribution. 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 */ 52 53 #include <sys/cdefs.h> 54 __FBSDID("$FreeBSD$"); 55 56 /** 57 * @file 58 * 59 * @brief This file contains the method implementations for the 60 * SCIF_SAS_STP_IO_REQUEST object. The contents will implement 61 * SATA/STP specific functionality. 62 */ 63 64 #include <dev/isci/scil/scif_sas_stp_io_request.h> 65 #include <dev/isci/scil/scif_sas_stp_remote_device.h> 66 #include <dev/isci/scil/scif_sas_logger.h> 67 #include <dev/isci/scil/scif_sas_controller.h> 68 69 #include <dev/isci/scil/sci_status.h> 70 #include <dev/isci/scil/scic_io_request.h> 71 72 #include <dev/isci/scil/sati.h> 73 #include <dev/isci/scil/sati_atapi.h> 74 #include <dev/isci/scil/intel_sat.h> 75 #include <dev/isci/scil/sati_util.h> 76 #include <dev/isci/scil/sati_callbacks.h> 77 78 //****************************************************************************** 79 // P R I V A T E M E T H O D S 80 //****************************************************************************** 81 82 /** 83 * @brief This method provides SATA/STP CONSTRUCTED state specific handling 84 * for when the user attempts to start the supplied IO request. It 85 * will allocate NCQ tags if necessary. 86 * 87 * @param[in] io_request This parameter specifies the IO request object 88 * to be started. 89 * 90 * @return This method returns a value indicating if the IO request was 91 * successfully started or not. 92 * @retval SCI_SUCCESS This return value indicates successful starting 93 * of the IO request. 94 */ 95 static 96 SCI_STATUS scif_sas_stp_io_request_constructed_start_handler( 97 SCI_BASE_REQUEST_T * io_request 98 ) 99 { 100 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) io_request; 101 102 SCIF_LOG_TRACE(( 103 sci_base_object_get_logger(io_request), 104 SCIF_LOG_OBJECT_IO_REQUEST, 105 "scif_sas_stp_io_request_constructed_start_handler(0x%x) enter\n", 106 io_request 107 )); 108 109 if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_FPDMA) 110 { 111 SATA_FIS_REG_H2D_T * fis; 112 113 // For NCQ, we need to attempt to allocate an available tag. 114 fw_io->parent.stp.ncq_tag = scif_sas_stp_remote_device_allocate_ncq_tag( 115 fw_io->parent.device 116 ); 117 118 if (fw_io->parent.stp.ncq_tag == SCIF_SAS_INVALID_NCQ_TAG) 119 return SCI_FAILURE_NO_NCQ_TAG_AVAILABLE; 120 121 // Set the NCQ tag in the host to device register FIS (upper 5 bits 122 // of the 8-bit sector count register). 123 fis = scic_stp_io_request_get_h2d_reg_address(fw_io->parent.core_object); 124 fis->sector_count = (fw_io->parent.stp.ncq_tag << 3); 125 126 // The Core also requires that we inform it separately regarding the 127 // NCQ tag for this IO. 128 scic_stp_io_request_set_ncq_tag( 129 fw_io->parent.core_object, fw_io->parent.stp.ncq_tag 130 ); 131 } 132 133 return SCI_SUCCESS; 134 } 135 136 /** 137 * @brief This method provides SATA/STP CONSTRUCTED state specific handling 138 * for when the user attempts to complete the supplied IO request. 139 * This method will be invoked in the event the call to start the 140 * core IO request fails for some reason. In this situation, the 141 * NCQ tag will be freed. 142 * 143 * @param[in] io_request This parameter specifies the IO request object 144 * to be started. 145 * 146 * @return This method returns a value indicating if the IO request was 147 * successfully started or not. 148 * @retval SCI_SUCCESS This return value indicates successful starting 149 * of the IO request. 150 */ 151 static 152 SCI_STATUS scif_sas_stp_io_request_constructed_complete_handler( 153 SCI_BASE_REQUEST_T * io_request 154 ) 155 { 156 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) io_request; 157 158 SCIF_LOG_TRACE(( 159 sci_base_object_get_logger(io_request), 160 SCIF_LOG_OBJECT_IO_REQUEST, 161 "scif_sas_stp_io_request_constructed_complete_handler(0x%x) enter\n", 162 io_request 163 )); 164 165 if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_FPDMA) 166 { 167 // For NCQ, we need to return the tag back to the free pool. 168 if (fw_io->parent.stp.ncq_tag != SCIF_SAS_INVALID_NCQ_TAG) 169 scif_sas_stp_remote_device_free_ncq_tag( 170 fw_io->parent.device, fw_io->parent.stp.ncq_tag 171 ); 172 } 173 174 sati_sequence_terminate(&fw_io->parent.stp.sequence, fw_io, fw_io); 175 176 return SCI_SUCCESS; 177 } 178 /** 179 * @brief This method provides SATA/STP STARTED state specific handling for 180 * when the user attempts to complete the supplied IO request. 181 * It will perform data/response translation and free NCQ tags 182 * if necessary. 183 * 184 * @param[in] io_request This parameter specifies the IO request object 185 * to be started. 186 * 187 * @return This method returns a value indicating if the IO request was 188 * successfully completed or not. 189 */ 190 static 191 SCI_STATUS scif_sas_stp_core_cb_io_request_complete_handler( 192 SCIF_SAS_CONTROLLER_T * fw_controller, 193 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 194 SCIF_SAS_REQUEST_T * fw_request, 195 SCI_STATUS * completion_status 196 ) 197 { 198 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) fw_request; 199 200 SCIF_LOG_TRACE(( 201 sci_base_object_get_logger(fw_controller), 202 SCIF_LOG_OBJECT_IO_REQUEST, 203 "scif_sas_stp_core_cb_io_request_complete_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 204 fw_controller, fw_device, fw_request, *completion_status 205 )); 206 207 if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_FPDMA) 208 scif_sas_stp_remote_device_free_ncq_tag( 209 fw_request->device, fw_io->parent.stp.ncq_tag 210 ); 211 212 // Translating the response is only necessary if: 213 // - some sort of error occurred resulting in having the error bit 214 // set in the ATA status register and values to decode in the 215 // ATA error register. 216 // - the command returns information in the register FIS itself, 217 // which requires translation. 218 // - the request completed ok but the sequence requires a callback 219 // to possibly continue the translation 220 if ((*completion_status == SCI_FAILURE_IO_RESPONSE_VALID) || 221 ((sati_cb_do_translate_response(fw_request)) && 222 (*completion_status != SCI_FAILURE_IO_TERMINATED))) 223 { 224 SATI_STATUS sati_status = sati_translate_command_response( 225 &fw_io->parent.stp.sequence, fw_io, fw_io 226 ); 227 if (sati_status == SATI_COMPLETE) 228 *completion_status = SCI_SUCCESS; 229 else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA) 230 *completion_status = SCI_FAILURE_IO_RESPONSE_VALID; 231 else if (sati_status == SATI_SEQUENCE_INCOMPLETE) 232 { 233 // The translation indicates that additional SATA requests are 234 // necessary to finish the original SCSI request. As a result, 235 // do not complete the IO and begin the next stage of the 236 // translation. 237 return SCI_WARNING_SEQUENCE_INCOMPLETE; 238 } 239 else if (sati_status == SATI_COMPLETE_IO_DONE_EARLY) 240 *completion_status = SCI_SUCCESS_IO_DONE_EARLY; 241 else 242 { 243 // Something unexpected occurred during translation. Fail the 244 // IO request to the user. 245 *completion_status = SCI_FAILURE; 246 } 247 } 248 else if (*completion_status != SCI_SUCCESS) 249 { 250 SCIF_LOG_INFO(( 251 sci_base_object_get_logger(fw_controller), 252 SCIF_LOG_OBJECT_IO_REQUEST, 253 "Sequence Terminated(0x%x, 0x%x, 0x%x)\n", 254 fw_controller, fw_device, fw_request 255 )); 256 257 sati_sequence_terminate(&fw_io->parent.stp.sequence, fw_io, fw_io); 258 } 259 260 return SCI_SUCCESS; 261 } 262 263 #if !defined(DISABLE_ATAPI) 264 /** 265 * @brief This method provides STP PACKET io request STARTED state specific handling for 266 * when the user attempts to complete the supplied IO request. 267 * It will perform data/response translation. 268 * 269 * @param[in] io_request This parameter specifies the IO request object 270 * to be started. 271 * 272 * @return This method returns a value indicating if the IO request was 273 * successfully completed or not. 274 */ 275 static 276 SCI_STATUS scif_sas_stp_core_cb_packet_io_request_complete_handler( 277 SCIF_SAS_CONTROLLER_T * fw_controller, 278 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 279 SCIF_SAS_REQUEST_T * fw_request, 280 SCI_STATUS * completion_status 281 ) 282 { 283 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) fw_request; 284 SATI_STATUS sati_status; 285 286 SCIF_LOG_TRACE(( 287 sci_base_object_get_logger(fw_controller), 288 SCIF_LOG_OBJECT_IO_REQUEST, 289 "scif_sas_stp_packet_core_cb_io_request_complete_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 290 fw_controller, fw_device, fw_request, *completion_status 291 )); 292 293 if (*completion_status == SCI_FAILURE_IO_RESPONSE_VALID) 294 { 295 sati_status = sati_atapi_translate_command_response( 296 &fw_io->parent.stp.sequence, fw_io, fw_io 297 ); 298 299 if (sati_status == SATI_COMPLETE) 300 *completion_status = SCI_SUCCESS; 301 else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA) 302 *completion_status = SCI_FAILURE_IO_RESPONSE_VALID; 303 else if (sati_status == SATI_SEQUENCE_INCOMPLETE) 304 { 305 // The translation indicates that additional REQUEST SENSE command is 306 // necessary to finish the original SCSI request. As a result, 307 // do not complete the IO and begin the next stage of the IO. 308 return SCI_WARNING_SEQUENCE_INCOMPLETE; 309 } 310 else 311 { 312 // Something unexpected occurred during translation. Fail the 313 // IO request to the user. 314 *completion_status = SCI_FAILURE; 315 } 316 } 317 else if (*completion_status == SCI_SUCCESS && 318 fw_request->stp.sequence.state == SATI_SEQUENCE_STATE_INCOMPLETE) 319 { 320 //The internal Request Sense command is completed successfully. 321 sati_atapi_translate_request_sense_response( 322 &fw_io->parent.stp.sequence, fw_io, fw_io 323 ); 324 325 *completion_status = SCI_FAILURE_IO_RESPONSE_VALID; 326 } 327 328 return SCI_SUCCESS; 329 } 330 #endif // !defined(DISABLE_ATAPI) 331 332 //****************************************************************************** 333 // P R O T E C T E D M E T H O D S 334 //****************************************************************************** 335 336 /** 337 * @brief This method will construct the SATA/STP specific IO request 338 * object utilizing the SATI. 339 * 340 * @pre The scif_sas_request_construct() method should be invoked before 341 * calling this method. 342 * 343 * @param[in,out] stp_io_request This parameter specifies the stp_io_request 344 * to be constructed. 345 * 346 * @return Indicate if the construction was successful. 347 * @return SCI_FAILURE_NO_NCQ_TAG_AVAILABLE 348 * @return SCI_SUCCESS_IO_COMPLETE_BEFORE_START 349 * @return SCI_FAILURE_IO_RESPONSE_VALID 350 * @return SCI_FAILURE This return value indicates a change in the translator 351 * where a new return code has been given, but is not yet understood 352 * by this routine. 353 */ 354 SCI_STATUS scif_sas_stp_io_request_construct( 355 SCIF_SAS_IO_REQUEST_T * fw_io 356 ) 357 { 358 SATI_STATUS sati_status; 359 SCI_STATUS sci_status = SCI_FAILURE; 360 SCIF_SAS_REMOTE_DEVICE_T * fw_device = fw_io->parent.device; 361 362 SCIF_LOG_TRACE(( 363 sci_base_object_get_logger(fw_io), 364 SCIF_LOG_OBJECT_IO_REQUEST, 365 "scif_sas_stp_io_request_construct(0x%x) enter\n", 366 fw_io 367 )); 368 369 // The translator will indirectly invoke core methods to set the fields 370 // of the ATA register FIS inside of this method. 371 sati_status = sati_translate_command( 372 &fw_io->parent.stp.sequence, 373 &fw_device->protocol_device.stp_device.sati_device, 374 fw_io, 375 fw_io 376 ); 377 378 if (sati_status == SATI_SUCCESS) 379 { 380 // Allow the core to finish construction of the IO request. 381 sci_status = scic_io_request_construct_basic_sata(fw_io->parent.core_object); 382 fw_io->parent.state_handlers = &stp_io_request_constructed_handlers; 383 fw_io->parent.protocol_complete_handler 384 = scif_sas_stp_core_cb_io_request_complete_handler; 385 } 386 else if (sati_status == SATI_SUCCESS_SGL_TRANSLATED) 387 { 388 SCIC_IO_SATA_PARAMETERS_T parms; 389 parms.do_translate_sgl = FALSE; 390 391 // The translation actually already caused translation of the 392 // scatter gather list. So, call into the core through an API 393 // that will not attempt to translate the SGL. 394 scic_io_request_construct_advanced_sata( 395 fw_io->parent.core_object, &parms 396 ); 397 fw_io->parent.state_handlers = &stp_io_request_constructed_handlers; 398 fw_io->parent.protocol_complete_handler 399 = scif_sas_stp_core_cb_io_request_complete_handler; 400 // Done with translation 401 sci_status = SCI_SUCCESS; 402 } 403 else if (sati_status == SATI_COMPLETE) 404 sci_status = SCI_SUCCESS_IO_COMPLETE_BEFORE_START; 405 else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA) 406 sci_status = SCI_FAILURE_IO_RESPONSE_VALID; 407 else 408 { 409 SCIF_LOG_ERROR(( 410 sci_base_object_get_logger(fw_io), 411 SCIF_LOG_OBJECT_IO_REQUEST, 412 "Unexpected SAT translation failure 0x%x\n", 413 fw_io 414 )); 415 } 416 417 return sci_status; 418 } 419 420 421 #if !defined(DISABLE_ATAPI) 422 /** 423 * @brief This method will construct the STP PACKET protocol specific IO 424 * request object. 425 * 426 * @pre The scif_sas_request_construct() method should be invoked before 427 * calling this method. 428 * 429 * @param[in,out] fw_io This parameter specifies the stp packet io request 430 * to be constructed. 431 * 432 * @return Indicate if the construction was successful. 433 * @return SCI_SUCCESS_IO_COMPLETE_BEFORE_START 434 * @return SCI_FAILURE_IO_RESPONSE_VALID 435 * @return SCI_FAILURE This return value indicates a change in the translator 436 * where a new return code has been given, but is not yet understood 437 * by this routine. 438 */ 439 SCI_STATUS scif_sas_stp_packet_io_request_construct( 440 SCIF_SAS_IO_REQUEST_T * fw_io 441 ) 442 { 443 SATI_STATUS sati_status; 444 SCI_STATUS sci_status = SCI_FAILURE; 445 SCIF_SAS_REMOTE_DEVICE_T * fw_device = fw_io->parent.device; 446 447 SCIF_LOG_TRACE(( 448 sci_base_object_get_logger(fw_io), 449 SCIF_LOG_OBJECT_IO_REQUEST, 450 "scif_sas_stp_packet_io_request_construct(0x%x) enter\n", 451 fw_io 452 )); 453 454 sati_status = sati_atapi_translate_command( 455 &fw_io->parent.stp.sequence, 456 &fw_device->protocol_device.stp_device.sati_device, 457 fw_io, 458 fw_io 459 ); 460 461 if (sati_status == SATI_SUCCESS) 462 { 463 // Allow the core to finish construction of the IO request. 464 sci_status = scic_io_request_construct_basic_sata(fw_io->parent.core_object); 465 466 fw_io->parent.protocol_complete_handler 467 = scif_sas_stp_core_cb_packet_io_request_complete_handler; 468 } 469 else if (sati_status == SATI_COMPLETE) 470 sci_status = SCI_SUCCESS_IO_COMPLETE_BEFORE_START; 471 else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA) 472 sci_status = SCI_FAILURE_IO_RESPONSE_VALID; 473 else 474 { 475 SCIF_LOG_ERROR(( 476 sci_base_object_get_logger(fw_io), 477 SCIF_LOG_OBJECT_IO_REQUEST, 478 "Unexpected SAT ATAPI translation failure 0x%x\n", 479 fw_io 480 )); 481 } 482 483 return sci_status; 484 } 485 #endif 486 487 488 #if !defined(DISABLE_ATAPI) 489 /** 490 * @brief This method will get the number of bytes transferred in an packet IO. 491 * 492 * @param[in] fw_io This parameter specifies the stp packet io request whose 493 * actual transferred length is to be retrieved. 494 * 495 * @return Actual length of transferred data. 496 */ 497 U32 scif_sas_stp_packet_io_request_get_number_of_bytes_transferred( 498 SCIF_SAS_IO_REQUEST_T * fw_io 499 ) 500 { 501 SCI_IO_REQUEST_HANDLE_T scic_io = scif_io_request_get_scic_handle(fw_io); 502 SCI_IO_STATUS io_status = scic_request_get_sci_status (scic_io); 503 U32 actual_data_length; 504 505 if (io_status == SCI_IO_FAILURE_RESPONSE_VALID) 506 actual_data_length = 0; 507 else if (io_status == SCI_IO_SUCCESS_IO_DONE_EARLY) 508 { 509 actual_data_length = sati_atapi_translate_number_of_bytes_transferred( 510 &fw_io->parent.stp.sequence, fw_io, fw_io); 511 512 if (actual_data_length == 0) 513 actual_data_length = 514 scic_io_request_get_number_of_bytes_transferred(scic_io); 515 } 516 else 517 actual_data_length = 518 scic_io_request_get_number_of_bytes_transferred(scic_io); 519 520 return actual_data_length; 521 } 522 #endif 523 524 525 //****************************************************************************** 526 // P U B L I C M E T H O D S 527 //****************************************************************************** 528 529 BOOL scic_cb_io_request_do_copy_rx_frames( 530 void * scic_user_io_request 531 ) 532 { 533 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) scic_user_io_request; 534 535 SCIF_LOG_TRACE(( 536 sci_base_object_get_logger(fw_io), 537 SCIF_LOG_OBJECT_IO_REQUEST, 538 "scic_cb_io_request_do_copy_rx_frames(0x%x) enter\n", 539 fw_io 540 )); 541 542 // If the translation was a PIO DATA IN (i.e. read) and the request 543 // was actually a READ payload operation, then copy the data, since 544 // there will be SGL space allocated for the transfer. 545 if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_PIO_DATA_IN) 546 { 547 if ( 548 (fw_io->parent.stp.sequence.type == SATI_SEQUENCE_ATA_PASSTHROUGH_12) 549 || (fw_io->parent.stp.sequence.type == SATI_SEQUENCE_ATA_PASSTHROUGH_16) 550 || ( 551 (fw_io->parent.stp.sequence.type >= SATI_SEQUENCE_TYPE_READ_MIN) 552 && (fw_io->parent.stp.sequence.type <= SATI_SEQUENCE_TYPE_READ_MAX) 553 ) 554 ) 555 { 556 SCIF_LOG_TRACE(( 557 sci_base_object_get_logger(fw_io), 558 SCIF_LOG_OBJECT_IO_REQUEST, 559 "scic_cb_io_request_do_copy_rx_frames(0x%x) TRUE\n", 560 fw_io 561 )); 562 return TRUE; 563 } 564 } 565 566 // For all other requests we leave the data in the core buffers. 567 // This allows the translation to translate without having to have 568 // separate space allocated into which to copy the data. 569 return FALSE; 570 } 571 572 // --------------------------------------------------------------------------- 573 574 U8 scic_cb_request_get_sat_protocol( 575 void * scic_user_io_request 576 ) 577 { 578 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) scic_user_io_request; 579 580 return fw_io->parent.stp.sequence.protocol; 581 } 582 583 U8 *scic_cb_io_request_get_virtual_address_from_sgl( 584 void * scic_user_io_request, 585 U32 byte_offset 586 ) 587 { 588 SCIF_SAS_REQUEST_T *fw_request = 589 (SCIF_SAS_REQUEST_T *) sci_object_get_association(scic_user_io_request); 590 591 return scif_cb_io_request_get_virtual_address_from_sgl( 592 sci_object_get_association(fw_request), 593 byte_offset 594 ); 595 } 596 597 #ifdef ENABLE_OSSL_COPY_BUFFER 598 void scic_cb_io_request_copy_buffer( 599 void * scic_user_io_request, 600 U8 *source_addr, 601 U32 offset, 602 U32 length 603 ) 604 { 605 SCIF_SAS_REQUEST_T *fw_request = 606 (SCIF_SAS_REQUEST_T *)sci_object_get_association(scic_user_io_request); 607 608 return scif_cb_io_request_copy_buffer( 609 sci_object_get_association(fw_request), 610 source_addr, 611 offset, 612 length 613 ); 614 } 615 #endif 616 // --------------------------------------------------------------------------- 617 618 SCI_BASE_REQUEST_STATE_HANDLER_T stp_io_request_constructed_handlers = 619 { 620 scif_sas_stp_io_request_constructed_start_handler, 621 scif_sas_io_request_constructed_abort_handler, 622 scif_sas_stp_io_request_constructed_complete_handler, 623 scif_sas_io_request_default_destruct_handler 624 }; 625 626