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 implementation of the SCIF_SAS_IO_REQUEST 60 * object. 61 */ 62 63 64 #include <dev/isci/scil/scic_io_request.h> 65 #include <dev/isci/scil/scic_remote_device.h> 66 #include <dev/isci/scil/scic_user_callback.h> 67 #include <dev/isci/scil/scic_controller.h> 68 #include <dev/isci/scil/scif_user_callback.h> 69 70 #include <dev/isci/scil/scif_sas_controller.h> 71 #include <dev/isci/scil/scif_sas_domain.h> 72 #include <dev/isci/scil/scif_sas_remote_device.h> 73 #include <dev/isci/scil/scif_sas_io_request.h> 74 #include <dev/isci/scil/scif_sas_task_request.h> 75 #include <dev/isci/scil/scif_sas_stp_io_request.h> 76 #include <dev/isci/scil/scif_sas_logger.h> 77 #include <dev/isci/scil/scif_sas_smp_io_request.h> 78 #include <dev/isci/scil/sci_fast_list.h> 79 #include <dev/isci/scil/sati.h> 80 #include <dev/isci/scil/intel_sat.h> 81 #include <dev/isci/scil/sati_translator_sequence.h> 82 83 /** 84 * @brief This method represents common functionality for the 85 * scif_io_request_construct() and scif_sas_io_request_continue() 86 * methods. 87 * 88 * @return This method returns an indication as to whether the 89 * construction succeeded. 90 */ 91 static 92 SCI_STATUS scif_sas_io_request_construct( 93 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 94 SCIF_SAS_IO_REQUEST_T * fw_io, 95 U16 io_tag, 96 void * user_io_request_object, 97 SCI_IO_REQUEST_HANDLE_T * scif_io_request, 98 BOOL is_initial_construction 99 ) 100 { 101 SCI_STATUS status; 102 SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; 103 104 scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); 105 106 //Currently, all the io requests sent to smp target are internal. 107 //so we fail all the external io toward to it. 108 //Todo: is there a better way to handle external io to smp target? 109 if (dev_protocols.u.bits.attached_smp_target) 110 return SCI_FAILURE_INVALID_REMOTE_DEVICE; 111 112 SCIF_LOG_TRACE(( 113 sci_base_object_get_logger(fw_device), 114 SCIF_LOG_OBJECT_IO_REQUEST, 115 "scif_sas_io_request_construct(0x%x,0x%x,0x%x,0x%x,0x%x,0x%x) enter\n", 116 fw_device, fw_io, io_tag, user_io_request_object, scif_io_request, 117 is_initial_construction 118 )); 119 120 // Initialize the users handle to the framework IO request. 121 *scif_io_request = fw_io; 122 123 // Construct the parent object first in order to ensure logging can 124 // function. 125 scif_sas_request_construct( 126 &fw_io->parent, 127 fw_device, 128 sci_base_object_get_logger(fw_device), 129 scif_sas_io_request_state_table 130 ); 131 132 status = scic_io_request_construct( 133 fw_device->domain->controller->core_object, 134 fw_device->core_object, 135 io_tag, 136 fw_io, 137 ((U8 *)fw_io) + sizeof(SCIF_SAS_IO_REQUEST_T), 138 &fw_io->parent.core_object 139 ); 140 141 if (status == SCI_SUCCESS) 142 { 143 // These associations must be set early for the core io request 144 // object construction to complete correctly as there will be 145 // callbacks into the user driver framework during core construction 146 sci_object_set_association(fw_io, user_io_request_object); 147 sci_object_set_association(fw_io->parent.core_object, fw_io); 148 149 // Perform protocol specific core IO request construction. 150 if (dev_protocols.u.bits.attached_ssp_target) 151 status = scic_io_request_construct_basic_ssp(fw_io->parent.core_object); 152 else if (dev_protocols.u.bits.attached_stp_target) 153 { 154 if (is_initial_construction == TRUE) 155 sati_sequence_construct(&fw_io->parent.stp.sequence); 156 157 #if !defined(DISABLE_ATAPI) 158 if (!scic_remote_device_is_atapi(fw_device->core_object)) 159 { 160 #endif 161 status = scif_sas_stp_io_request_construct(fw_io); 162 163 #if !defined(DISABLE_ATAPI) 164 } 165 else 166 status = scif_sas_stp_packet_io_request_construct(fw_io); 167 #endif 168 } 169 170 sci_base_state_machine_logger_initialize( 171 &fw_io->parent.parent.state_machine_logger, 172 &fw_io->parent.parent.state_machine, 173 &fw_io->parent.parent.parent, 174 scif_cb_logger_log_states, 175 "SCIF_IO_REQUEST_T", "base_state_machine", 176 SCIF_LOG_OBJECT_IO_REQUEST 177 ); 178 } 179 180 return status; 181 } 182 183 //****************************************************************************** 184 //* P U B L I C M E T H O D S 185 //****************************************************************************** 186 187 U32 scif_io_request_get_object_size( 188 void 189 ) 190 { 191 return (sizeof(SCIF_SAS_IO_REQUEST_T) + scic_io_request_get_object_size()); 192 } 193 194 // ---------------------------------------------------------------------------- 195 U32 scif_io_request_get_number_of_bytes_transferred( 196 SCI_IO_REQUEST_HANDLE_T scif_io_request 197 ) 198 { 199 SCIF_SAS_IO_REQUEST_T * fw_request = (SCIF_SAS_IO_REQUEST_T*) scif_io_request; 200 201 if(scic_io_request_get_protocol(scif_io_request_get_scic_handle(scif_io_request)) 202 == SCIC_STP_PROTOCOL) 203 { 204 U16 sati_data_bytes_set = 205 sati_get_number_data_bytes_set(&(fw_request->parent.stp.sequence)); 206 207 if (sati_data_bytes_set != 0) 208 return sati_data_bytes_set; 209 else 210 { 211 #if !defined(DISABLE_ATAPI) 212 U8 sat_protocol = fw_request->parent.stp.sequence.protocol; 213 if ( sat_protocol & SAT_PROTOCOL_PACKET) 214 return 215 scif_sas_stp_packet_io_request_get_number_of_bytes_transferred(fw_request); 216 else 217 #endif 218 return scic_io_request_get_number_of_bytes_transferred( 219 scif_io_request_get_scic_handle(scif_io_request)); 220 } 221 } 222 else 223 { 224 return scic_io_request_get_number_of_bytes_transferred( 225 scif_io_request_get_scic_handle(scif_io_request)); 226 } 227 } 228 229 // --------------------------------------------------------------------------- 230 231 SCI_STATUS scif_io_request_construct( 232 SCI_CONTROLLER_HANDLE_T scif_controller, 233 SCI_REMOTE_DEVICE_HANDLE_T scif_remote_device, 234 U16 io_tag, 235 void * user_io_request_object, 236 void * io_request_memory, 237 SCI_IO_REQUEST_HANDLE_T * scif_io_request 238 ) 239 { 240 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 241 io_request_memory; 242 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 243 scif_remote_device; 244 245 return scif_sas_io_request_construct( 246 fw_device, 247 fw_io, 248 io_tag, 249 user_io_request_object, 250 scif_io_request, 251 TRUE 252 ); 253 } 254 255 // --------------------------------------------------------------------------- 256 257 SCI_STATUS scif_request_construct( 258 SCI_CONTROLLER_HANDLE_T scif_controller, 259 SCI_REMOTE_DEVICE_HANDLE_T scif_remote_device, 260 U16 io_tag, 261 void * user_io_request_object, 262 void * io_request_memory, 263 SCI_IO_REQUEST_HANDLE_T * scif_io_request 264 ) 265 { 266 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 267 io_request_memory; 268 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 269 scif_remote_device; 270 SCI_STATUS status; 271 272 SCIF_LOG_TRACE(( 273 sci_base_object_get_logger(fw_device), 274 SCIF_LOG_OBJECT_IO_REQUEST, 275 "scif_io_request_construct(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) enter\n", 276 scif_controller, scif_remote_device, io_tag, user_io_request_object, 277 io_request_memory, scif_io_request 278 )); 279 280 // Step 1: Create the scif io request. 281 // Initialize the users handle to the framework IO request. 282 *scif_io_request = fw_io; 283 284 // Construct the parent object first in order to ensure logging can 285 // function. 286 scif_sas_request_construct( 287 &fw_io->parent, 288 fw_device, 289 sci_base_object_get_logger(fw_device), 290 scif_sas_io_request_state_table 291 ); 292 293 status = scic_io_request_construct( 294 (void *) ((SCIF_SAS_CONTROLLER_T *)scif_controller)->core_object, 295 (void *) fw_device->core_object, 296 io_tag, 297 fw_io, 298 (U8 *)io_request_memory + sizeof(SCIF_SAS_IO_REQUEST_T), 299 &fw_io->parent.core_object 300 ); 301 302 if (status == SCI_SUCCESS) 303 { 304 // These associations must be set early for the core io request 305 // object construction to complete correctly as there will be 306 // callbacks into the user driver framework during core construction 307 sci_object_set_association(fw_io, user_io_request_object); 308 sci_object_set_association(fw_io->parent.core_object, fw_io); 309 310 sci_base_state_machine_logger_initialize( 311 &fw_io->parent.parent.state_machine_logger, 312 &fw_io->parent.parent.state_machine, 313 &fw_io->parent.parent.parent, 314 scif_cb_logger_log_states, 315 "SCIF_IO_REQUEST_T", "base_state_machine", 316 SCIF_LOG_OBJECT_IO_REQUEST 317 ); 318 } 319 320 return status; 321 } 322 323 // ---------------------------------------------------------------------------- 324 325 SCI_STATUS scif_io_request_construct_with_core ( 326 SCI_CONTROLLER_HANDLE_T scif_controller, 327 SCI_REMOTE_DEVICE_HANDLE_T scif_remote_device, 328 void * scic_io_request, 329 void * user_io_request_object, 330 void * io_request_memory, 331 SCI_IO_REQUEST_HANDLE_T * scif_io_request 332 ) 333 { 334 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 335 io_request_memory; 336 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 337 scif_remote_device; 338 SCI_STATUS status = SCI_SUCCESS; 339 340 SCIF_LOG_TRACE(( 341 sci_base_object_get_logger(fw_device), 342 SCIF_LOG_OBJECT_IO_REQUEST, 343 "scif_io_request_construct_pass_through(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 344 scif_remote_device, user_io_request_object, 345 io_request_memory, scif_io_request 346 )); 347 348 // Initialize the users handle to the framework IO request. 349 *scif_io_request = fw_io; 350 351 // Construct the parent object first in order to ensure logging can 352 // function. 353 scif_sas_request_construct( 354 &fw_io->parent, 355 fw_device, 356 sci_base_object_get_logger(fw_device), 357 scif_sas_io_request_state_table 358 ); 359 360 fw_io->parent.core_object = scic_io_request; 361 362 //set association 363 sci_object_set_association(fw_io, user_io_request_object); 364 sci_object_set_association(fw_io->parent.core_object, fw_io); 365 366 367 sci_base_state_machine_logger_initialize( 368 &fw_io->parent.parent.state_machine_logger, 369 &fw_io->parent.parent.state_machine, 370 &fw_io->parent.parent.parent, 371 scif_cb_logger_log_states, 372 "SCIF_IO_REQUEST_T", "base_state_machine", 373 SCIF_LOG_OBJECT_IO_REQUEST 374 ); 375 376 return status; 377 } 378 379 // --------------------------------------------------------------------------- 380 381 void * scif_io_request_get_response_iu_address( 382 SCI_IO_REQUEST_HANDLE_T scif_io_request 383 ) 384 { 385 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*)scif_io_request; 386 387 return (scic_io_request_get_response_iu_address(fw_io->parent.core_object )); 388 } 389 390 // --------------------------------------------------------------------------- 391 392 SCI_IO_REQUEST_HANDLE_T scif_io_request_get_scic_handle( 393 SCI_IO_REQUEST_HANDLE_T scif_io_request 394 ) 395 { 396 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) scif_io_request; 397 return fw_io->parent.core_object; 398 } 399 400 // --------------------------------------------------------------------------- 401 402 void scic_cb_io_request_complete( 403 SCI_CONTROLLER_HANDLE_T controller, 404 SCI_REMOTE_DEVICE_HANDLE_T remote_device, 405 SCI_IO_REQUEST_HANDLE_T io_request, 406 SCI_IO_STATUS completion_status 407 ) 408 { 409 SCI_STATUS status; 410 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) 411 sci_object_get_association(controller); 412 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 413 sci_object_get_association(remote_device); 414 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) 415 sci_object_get_association(io_request); 416 417 SCIF_LOG_TRACE(( 418 sci_base_object_get_logger(controller), 419 SCIF_LOG_OBJECT_IO_REQUEST, 420 "scic_cb_io_request_complete(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 421 controller, remote_device, io_request, completion_status 422 )); 423 424 // Invoke the common completion handler routine. 425 // A non-successful return indicates we are not in a correct state to 426 // receive a completion notification for this request. 427 status = fw_request->state_handlers->complete_handler(&fw_request->parent); 428 429 // If the status indicates the completion handler was successful, then 430 // allow protocol specific completion processing to occur. 431 if (status == SCI_SUCCESS) 432 { 433 if (fw_request->protocol_complete_handler != NULL) 434 { 435 status = fw_request->protocol_complete_handler( 436 fw_controller, fw_device, fw_request, (SCI_STATUS *)&completion_status 437 ); 438 } 439 440 // If this isn't an internal framework IO request, then simply pass the 441 // notification up to the SCIF user. 442 if ( status == SCI_SUCCESS ) 443 { 444 if (fw_request->is_high_priority == FALSE) 445 { 446 if (fw_request->is_waiting_for_abort_task_set == FALSE) 447 { 448 scif_cb_io_request_complete( 449 fw_controller, fw_device, fw_request, completion_status); 450 } 451 else 452 { 453 // do nothing - will complete the I/O when the abort task 454 // set completes 455 } 456 } 457 else 458 scif_sas_controller_complete_high_priority_io( 459 fw_controller, fw_device, fw_request); 460 } 461 else if ( status == SCI_WARNING_SEQUENCE_INCOMPLETE ) 462 { 463 scif_sas_io_request_continue(fw_controller, fw_device, fw_request); 464 } 465 } 466 } 467 468 // --------------------------------------------------------------------------- 469 470 U32 scic_cb_io_request_get_transfer_length( 471 void * scic_user_io_request 472 ) 473 { 474 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 475 scic_user_io_request; 476 477 return (scif_cb_io_request_get_transfer_length( 478 fw_io->parent.parent.parent.associated_object 479 )); 480 } 481 482 // --------------------------------------------------------------------------- 483 484 SCI_IO_REQUEST_DATA_DIRECTION scic_cb_io_request_get_data_direction( 485 void * scic_user_io_request 486 ) 487 { 488 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 489 scic_user_io_request; 490 491 return (scif_cb_io_request_get_data_direction( 492 fw_io->parent.parent.parent.associated_object 493 )); 494 } 495 496 // --------------------------------------------------------------------------- 497 #ifndef SCI_SGL_OPTIMIZATION_ENABLED 498 void scic_cb_io_request_get_next_sge( 499 void * scic_user_io_request, 500 void * current_sge_address, 501 void **next_sge 502 ) 503 { 504 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 505 scic_user_io_request; 506 507 scif_cb_io_request_get_next_sge( 508 fw_io->parent.parent.parent.associated_object, 509 current_sge_address, 510 next_sge 511 ); 512 } 513 #endif 514 515 // --------------------------------------------------------------------------- 516 517 SCI_PHYSICAL_ADDRESS scic_cb_sge_get_address_field( 518 void * scic_user_io_request, 519 void * sge_address 520 ) 521 { 522 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 523 scic_user_io_request; 524 return scif_cb_sge_get_address_field( 525 fw_io->parent.parent.parent.associated_object, sge_address 526 ); 527 } 528 529 // --------------------------------------------------------------------------- 530 531 U32 scic_cb_sge_get_length_field( 532 void * scic_user_io_request, 533 void * sge_address 534 ) 535 { 536 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 537 scic_user_io_request; 538 539 return scif_cb_sge_get_length_field( 540 fw_io->parent.parent.parent.associated_object, 541 sge_address 542 ); 543 } 544 545 // --------------------------------------------------------------------------- 546 547 void * scic_cb_ssp_io_request_get_cdb_address( 548 void * scic_user_io_request 549 ) 550 { 551 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 552 scic_user_io_request; 553 554 return scif_cb_io_request_get_cdb_address( 555 fw_io->parent.parent.parent.associated_object 556 ); 557 } 558 559 // --------------------------------------------------------------------------- 560 561 U32 scic_cb_ssp_io_request_get_cdb_length( 562 void * scic_user_io_request 563 ) 564 { 565 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 566 scic_user_io_request; 567 568 return scif_cb_io_request_get_cdb_length( 569 fw_io->parent.parent.parent.associated_object 570 ); 571 } 572 573 // --------------------------------------------------------------------------- 574 575 #if !defined(DISABLE_ATAPI) 576 void * scic_cb_stp_packet_io_request_get_cdb_address( 577 void * scic_user_io_request 578 ) 579 { 580 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*)scic_user_io_request; 581 582 SATI_TRANSLATOR_SEQUENCE_T * sati_sequence = &fw_request->stp.sequence; 583 584 if (sati_sequence->state != SATI_SEQUENCE_STATE_INCOMPLETE) 585 return scif_cb_io_request_get_cdb_address( 586 fw_request->parent.parent.associated_object 587 ); 588 else 589 return 590 &(sati_sequence->command_specific_data.sati_atapi_data.request_sense_cdb); 591 } 592 #endif 593 594 // --------------------------------------------------------------------------- 595 596 #if !defined(DISABLE_ATAPI) 597 U32 scic_cb_stp_packet_io_request_get_cdb_length( 598 void * scic_user_io_request 599 ) 600 { 601 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) 602 scic_user_io_request; 603 604 SATI_TRANSLATOR_SEQUENCE_T * sati_sequence = &fw_request->stp.sequence; 605 606 if (sati_sequence->state != SATI_SEQUENCE_STATE_INCOMPLETE) 607 return scif_cb_io_request_get_cdb_length( 608 fw_request->parent.parent.associated_object 609 ); 610 else 611 return SATI_ATAPI_REQUEST_SENSE_CDB_LENGTH; 612 } 613 #endif 614 615 // --------------------------------------------------------------------------- 616 617 U32 scic_cb_ssp_io_request_get_lun( 618 void * scic_user_io_request 619 ) 620 { 621 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 622 scic_user_io_request; 623 624 return scif_cb_io_request_get_lun( 625 fw_io->parent.parent.parent.associated_object 626 ); 627 } 628 629 // --------------------------------------------------------------------------- 630 631 U32 scic_cb_ssp_io_request_get_task_attribute( 632 void * scic_user_io_request 633 ) 634 { 635 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 636 scic_user_io_request; 637 638 return scif_cb_io_request_get_task_attribute( 639 fw_io->parent.parent.parent.associated_object 640 ); 641 } 642 643 // --------------------------------------------------------------------------- 644 645 U32 scic_cb_ssp_io_request_get_command_priority( 646 void * scic_user_io_request 647 ) 648 { 649 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 650 scic_user_io_request; 651 652 return scif_cb_io_request_get_command_priority( 653 fw_io->parent.parent.parent.associated_object 654 ); 655 } 656 657 // --------------------------------------------------------------------------- 658 659 BOOL scic_cb_request_is_initial_construction( 660 void * scic_user_io_request 661 ) 662 { 663 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) 664 scic_user_io_request; 665 SCIF_SAS_REMOTE_DEVICE_T* fw_device = fw_request->device; 666 667 SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; 668 scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); 669 670 if (dev_protocols.u.bits.attached_stp_target 671 && fw_request->stp.sequence.state == SATI_SEQUENCE_STATE_INCOMPLETE) 672 return FALSE; 673 674 return TRUE; 675 } 676 677 678 //****************************************************************************** 679 //* P R O T E C T E D M E T H O D S 680 //****************************************************************************** 681 /** 682 * @brief This method constructs an scif sas smp request. 683 * 684 * @param[in] fw_controller The framework controller 685 * @param[in] fw_device The smp device that the smp request targets to. 686 * @param[in] fw_io_memory The memory space for the smp request. 687 * @param[in] core_io_memory The memory space for the core request. 688 * @param[in] io_tag The io tag for the internl io to be constructed. 689 * @param[in] smp_command A pointer to the smp request data structure according 690 * to SAS protocol. 691 * 692 * @return Indicate if the internal io was successfully constructed. 693 * @retval SCI_SUCCESS This value is returned if the internal io was 694 * successfully constructed. 695 * @retval SCI_FAILURE This value is returned if the internal io was failed to 696 * be constructed. 697 */ 698 SCI_STATUS scif_sas_io_request_construct_smp( 699 SCIF_SAS_CONTROLLER_T * fw_controller, 700 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 701 void * fw_io_memory, 702 void * core_io_memory, 703 U16 io_tag, 704 SMP_REQUEST_T * smp_command, 705 void * user_request_object 706 ) 707 { 708 SCIF_SAS_IO_REQUEST_T * fw_io = 709 (SCIF_SAS_IO_REQUEST_T*)fw_io_memory; 710 711 SCI_STATUS status = SCI_SUCCESS; 712 713 SCIF_LOG_TRACE(( 714 sci_base_object_get_logger(fw_device), 715 SCIF_LOG_OBJECT_IO_REQUEST, 716 "scif_sas_io_request_construct_smp(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) enter\n", 717 fw_controller, 718 fw_device, 719 fw_io_memory, 720 core_io_memory, 721 io_tag, 722 smp_command, 723 user_request_object 724 )); 725 726 // Construct the parent object first in order to ensure logging can 727 // function. 728 scif_sas_request_construct( 729 &fw_io->parent, 730 fw_device, 731 sci_base_object_get_logger(fw_controller), 732 scif_sas_io_request_state_table 733 ); 734 735 status = scic_io_request_construct( 736 fw_device->domain->controller->core_object, 737 fw_device->core_object, 738 io_tag, 739 (void*)fw_io, 740 (U8 *)core_io_memory, 741 &fw_io->parent.core_object 742 ); 743 744 if (status == SCI_SUCCESS) 745 { 746 //set object association. 747 sci_object_set_association(fw_io, user_request_object); 748 sci_object_set_association(fw_io->parent.core_object, fw_io); 749 750 scif_sas_smp_request_construct(&fw_io->parent, smp_command); 751 752 fw_io->parent.is_high_priority = TRUE; 753 754 sci_base_state_machine_logger_initialize( 755 &fw_io->parent.parent.state_machine_logger, 756 &fw_io->parent.parent.state_machine, 757 &fw_io->parent.parent.parent, 758 scif_cb_logger_log_states, 759 "SCIF_IO_REQUEST_T", "base_state_machine", 760 SCIF_LOG_OBJECT_IO_REQUEST 761 ); 762 } 763 764 return status; 765 } 766 767 768 /** 769 * @brief This method continues a scif sas request. 770 * 771 * @param[in] fw_controller The framework controller 772 * @param[in] fw_device The device that the IO request targets to. 773 * @param[in] fw_request The IO request to be continued. 774 * 775 * @return Indicate if the internal io was successfully constructed. 776 * @retval SCI_SUCCESS This value is returned if the internal io was 777 * successfully continued. 778 * @retval SCI_FAILURE This value is returned if the io was failed to 779 * be continued. 780 */ 781 SCI_STATUS scif_sas_io_request_continue( 782 SCIF_SAS_CONTROLLER_T * fw_controller, 783 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 784 SCIF_SAS_REQUEST_T * fw_request 785 ) 786 { 787 SCI_IO_REQUEST_HANDLE_T dummy_handle; 788 789 SCIF_LOG_TRACE(( 790 sci_base_object_get_logger(fw_request), 791 SCIF_LOG_OBJECT_IO_REQUEST, 792 "scif_sas_io_request_continue(0x%x, 0x%x, 0x%x) enter\n", 793 fw_controller, 794 fw_device, 795 fw_request 796 )); 797 798 //complete this io request in framework and core. 799 scif_controller_complete_io(fw_controller, fw_device, fw_request); 800 801 //construct next command in the sequence using the same memory. We pass 802 //a dummy pointer to let the framework user keep the pointer to this IO 803 //request untouched. 804 scif_sas_io_request_construct( 805 fw_device, 806 (SCIF_SAS_IO_REQUEST_T*)fw_request, 807 SCI_CONTROLLER_INVALID_IO_TAG, 808 (void *)sci_object_get_association(fw_request), 809 &dummy_handle, 810 FALSE 811 ); 812 813 //start the new constructed IO. 814 return (SCI_STATUS)scif_controller_start_io( 815 (SCI_CONTROLLER_HANDLE_T) fw_controller, 816 (SCI_REMOTE_DEVICE_HANDLE_T) fw_device, 817 (SCI_IO_REQUEST_HANDLE_T) fw_request, 818 SCI_CONTROLLER_INVALID_IO_TAG 819 ); 820 } 821