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