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 * 59 * @brief This file contains all of the state handler routines for each 60 * of the controller states defined by the SCI_BASE_CONTROLLER state 61 * machine. 62 */ 63 64 #include <dev/isci/scil/sci_util.h> 65 #include <dev/isci/scil/scic_controller.h> 66 #include <dev/isci/scil/scic_port.h> 67 #include <dev/isci/scil/scic_remote_device.h> 68 #include <dev/isci/scil/scic_io_request.h> 69 70 #include <dev/isci/scil/scif_sas_controller.h> 71 #include <dev/isci/scil/scif_sas_remote_device.h> 72 #include <dev/isci/scil/scif_sas_logger.h> 73 #include <dev/isci/scil/scif_sas_smp_remote_device.h> 74 75 //****************************************************************************** 76 //* P R I V A T E M E T H O D S 77 //****************************************************************************** 78 79 /** 80 * @brief This method simply executes the reset operation by entering 81 * the reset state and allowing the state to perform it's work. 82 * 83 * @param[in] fw_controller This parameter specifies the SAS framework 84 * controller for execute the reset. 85 * 86 * @return Indicate the status of the reset operation. Was it successful? 87 * @retval SCI_SUCCESS This value is returned if it was successfully reset. 88 */ 89 static 90 SCI_STATUS scif_sas_controller_execute_reset( 91 SCIF_SAS_CONTROLLER_T * fw_controller 92 ) 93 { 94 SCI_STATUS status; 95 96 SCIF_LOG_TRACE(( 97 sci_base_object_get_logger(fw_controller), 98 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_CONTROLLER_RESET, 99 "scif_sas_controller_execute_reset(0x%x) enter\n", 100 fw_controller 101 )); 102 103 //clean the timer to avoid timer leak. 104 scif_sas_controller_release_resource(fw_controller); 105 106 sci_base_state_machine_change_state( 107 &fw_controller->parent.state_machine, 108 SCI_BASE_CONTROLLER_STATE_RESETTING 109 ); 110 111 // Retrieve the status for the operations performed during the entrance 112 // to the resetting state were executing successfully. 113 status = fw_controller->operation_status; 114 fw_controller->operation_status = SCI_SUCCESS; 115 116 return status; 117 } 118 119 /** 120 * @brief This method checks that the memory descriptor list is valid 121 * and hasn't been corrupted in some way by the user. 122 * 123 * @param[in] fw_controller This parameter specifies the framework 124 * controller object for which to validation the MDL. 125 * 126 * @return This method returns a value indicating if the operation succeeded. 127 * @retval SCI_SUCCESS This value indicates that MDL is valid. 128 * @retval SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD This value indicates 129 * that some portion of the memory descriptor list is invalid. 130 */ 131 static 132 SCI_STATUS scif_sas_controller_validate_mdl( 133 SCIF_SAS_CONTROLLER_T * fw_controller 134 ) 135 { 136 BOOL is_mde_list_valid; 137 138 // Currently there is only a single MDE in the list. 139 is_mde_list_valid = sci_base_mde_is_valid( 140 &fw_controller->mdes[SCIF_SAS_MDE_INTERNAL_IO], 141 4, 142 fw_controller->internal_request_entries * 143 scif_sas_internal_request_get_object_size(), 144 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS 145 ); 146 147 if (is_mde_list_valid == FALSE) 148 return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD; 149 150 return SCI_SUCCESS; 151 } 152 153 154 /** 155 * @brief This method stops all the domains associated to this 156 * controller. 157 * 158 * @param[in] fw_controller This parameter specifies the framework 159 * controller object for whose remote devices are to be stopped. 160 * 161 * @return This method returns a value indicating if the operation succeeded. 162 * @retval SCI_SUCCESS This value indicates that all the devices are stopped. 163 * @retval SCI_FAILURE This value indicates certain failure during the process 164 * of stopping remote devices. 165 */ 166 static 167 SCI_STATUS scif_sas_controller_stop_domains( 168 SCIF_SAS_CONTROLLER_T * fw_controller 169 ) 170 { 171 U8 index; 172 SCI_STATUS status = SCI_SUCCESS; 173 SCIF_SAS_DOMAIN_T * fw_domain; 174 175 SCIF_LOG_TRACE(( 176 sci_base_object_get_logger(fw_controller), 177 SCIF_LOG_OBJECT_CONTROLLER, 178 "scif_sas_controller_stop_domains(0x%x) enter\n", 179 fw_controller 180 )); 181 182 for (index = 0; index < SCI_MAX_DOMAINS && status == SCI_SUCCESS; index++) 183 { 184 fw_domain = &fw_controller->domains[index]; 185 186 //Change this domain to STOPPING state. All the remote devices will be 187 //stopped subsquentially. 188 if (fw_domain->parent.state_machine.current_state_id == 189 SCI_BASE_DOMAIN_STATE_READY 190 || fw_domain->parent.state_machine.current_state_id == 191 SCI_BASE_DOMAIN_STATE_DISCOVERING) 192 { 193 sci_base_state_machine_change_state( 194 &fw_domain->parent.state_machine, SCI_BASE_DOMAIN_STATE_STOPPING 195 ); 196 } 197 } 198 199 return status; 200 } 201 202 203 /** 204 * @brief This method continue to stop the controller after clear affiliation 205 * is done. 206 * 207 * @param[in] fw_controller This parameter specifies the framework 208 * controller object to be stopped. 209 * 210 * @return This method returns a value indicating if the operation succeeded. 211 * @retval SCI_SUCCESS This value indicates the controller_stop succeeds. 212 * @retval SCI_FAILURE This value indicates certain failure during the process 213 * of stopping controller. 214 */ 215 SCI_STATUS scif_sas_controller_continue_to_stop( 216 SCIF_SAS_CONTROLLER_T * fw_controller 217 ) 218 { 219 SCI_STATUS status; 220 221 SCIF_LOG_TRACE(( 222 sci_base_object_get_logger(fw_controller), 223 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN, 224 "scif_sas_controller_continue_to_stop (0x%x).\n", 225 fw_controller 226 )); 227 228 //stop all the domains and their remote devices. 229 status = scif_sas_controller_stop_domains(fw_controller); 230 231 if (status == SCI_SUCCESS) 232 { 233 // Attempt to stop the core controller. 234 status = scic_controller_stop(fw_controller->core_object, 0); 235 236 if (status != SCI_SUCCESS) 237 { 238 SCIF_LOG_ERROR(( 239 sci_base_object_get_logger(fw_controller), 240 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN, 241 "Controller:0x%x Status:0x%x unable to stop controller.\n", 242 fw_controller, status 243 )); 244 245 sci_base_state_machine_change_state( 246 &fw_controller->parent.state_machine, 247 SCI_BASE_CONTROLLER_STATE_FAILED 248 ); 249 } 250 } 251 else 252 { 253 SCIF_LOG_ERROR(( 254 sci_base_object_get_logger(fw_controller), 255 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN, 256 "Controller:0x%x Status:0x%x unable to stop domains.\n", 257 fw_controller, status 258 )); 259 260 sci_base_state_machine_change_state( 261 &fw_controller->parent.state_machine, 262 SCI_BASE_CONTROLLER_STATE_FAILED 263 ); 264 } 265 266 return status; 267 } 268 269 270 //****************************************************************************** 271 //* R E S E T H A N D L E R S 272 //****************************************************************************** 273 274 /** 275 * @brief This method provides RESET state specific handling for 276 * when a user attempts to initialize a controller. This is a legal 277 * state in which to attempt an initialize call. 278 * 279 * @param[in] controller This parameter specifies the controller object 280 * on which the user is attempting to perform an initialize 281 * operation. 282 * 283 * @return This method returns an indication of whether the initialize 284 * operation succeeded. 285 * @retval SCI_SUCCESS This value when the initialization completes 286 * successfully. 287 */ 288 static 289 SCI_STATUS scif_sas_controller_reset_initialize_handler( 290 SCI_BASE_CONTROLLER_T * controller 291 ) 292 { 293 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)controller; 294 SCI_STATUS status; 295 U32 index; 296 297 SCIF_LOG_TRACE(( 298 sci_base_object_get_logger(fw_controller), 299 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION, 300 "scif_sas_controller_reset_initialize_handler(0x%x) enter\n", 301 controller 302 )); 303 304 sci_base_state_machine_change_state( 305 &fw_controller->parent.state_machine, 306 SCI_BASE_CONTROLLER_STATE_INITIALIZING 307 ); 308 309 scif_sas_controller_build_mdl(fw_controller); 310 311 // Perform any domain object initialization that is necessary. 312 for (index = 0; index < SCI_MAX_DOMAINS; index++) 313 scif_sas_domain_initialize(&fw_controller->domains[index]); 314 315 scif_cb_lock_associate(fw_controller, &fw_controller->hprq.lock); 316 317 // Attempt to initialize the core controller. 318 status = scic_controller_initialize(fw_controller->core_object); 319 if (status == SCI_SUCCESS) 320 { 321 sci_base_state_machine_change_state( 322 &fw_controller->parent.state_machine, 323 SCI_BASE_CONTROLLER_STATE_INITIALIZED 324 ); 325 } 326 327 if (status != SCI_SUCCESS) 328 { 329 // Initialization failed, Release resources and do not change state 330 scif_sas_controller_release_resource(fw_controller); 331 332 SCIF_LOG_ERROR(( 333 sci_base_object_get_logger(fw_controller), 334 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION, 335 "Controller:0x%x Status:0x%x unable to successfully initialize.\n", 336 fw_controller, status 337 )); 338 } 339 340 return status; 341 } 342 343 //****************************************************************************** 344 //* I N I T I A L I Z E D H A N D L E R S 345 //****************************************************************************** 346 347 /** 348 * @brief This method provides INITIALIZED state specific handling for 349 * when a user attempts to start a controller. 350 * 351 * @param[in] controller This parameter specifies the controller object 352 * on which the user is attempting to perform a start 353 * operation. 354 * @param[in] timeout This parameter specifies the timeout value (in 355 * milliseconds) to be utilized for this operation. 356 * 357 * @return This method returns an indication of whether the start operation 358 * succeeded. 359 * @retval SCI_SUCCESS This value is returned when the start operation 360 * begins successfully. 361 */ 362 static 363 SCI_STATUS scif_sas_controller_initialized_start_handler( 364 SCI_BASE_CONTROLLER_T * controller, 365 U32 timeout 366 ) 367 { 368 SCI_STATUS status = SCI_SUCCESS; 369 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)controller; 370 U16 index = 0; 371 372 SCI_PHYSICAL_MEMORY_DESCRIPTOR_T internal_reqeust_mde = 373 fw_controller->mdes[SCIF_SAS_MDE_INTERNAL_IO]; 374 375 void * internal_request_virtual_address = internal_reqeust_mde.virtual_address; 376 POINTER_UINT address = (POINTER_UINT)internal_request_virtual_address; 377 378 SCIF_LOG_TRACE(( 379 sci_base_object_get_logger(fw_controller), 380 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION, 381 "scif_sas_controller_initialized_start_handler(0x%x, 0x%x) enter\n", 382 controller, timeout 383 )); 384 385 sci_base_state_machine_change_state( 386 &fw_controller->parent.state_machine, 387 SCI_BASE_CONTROLLER_STATE_STARTING 388 ); 389 390 status = scif_sas_controller_validate_mdl(fw_controller); 391 392 // initialization work for internal request path. It must be done before 393 // starting domain. 394 if (status == SCI_SUCCESS) 395 { 396 // fill in the sci_pool for internal requests. 397 sci_pool_initialize(fw_controller->internal_request_memory_pool); 398 399 for (index = 0; index < fw_controller->internal_request_entries; index++) 400 { 401 sci_pool_put(fw_controller->internal_request_memory_pool, address); 402 403 address += scif_sas_internal_request_get_object_size(); 404 } 405 406 // Using DPC for starting internal IOs, if yes, we need to intialize 407 // DPC here. 408 scif_cb_start_internal_io_task_create(fw_controller); 409 } 410 411 if (status == SCI_SUCCESS) 412 { 413 // Kick-start the domain state machines and, by association, the 414 // core port's. 415 416 // This will ensure we get valid port objects supplied with link up 417 // messages. 418 for (index = 0; 419 (index < SCI_MAX_DOMAINS) && (status == SCI_SUCCESS); 420 index++) 421 { 422 sci_base_state_machine_change_state( 423 &fw_controller->domains[index].parent.state_machine, 424 SCI_BASE_DOMAIN_STATE_STARTING 425 ); 426 status = fw_controller->domains[index].operation.status; 427 } 428 } 429 430 // Validate that all the domain state machines began successfully. 431 if (status != SCI_SUCCESS) 432 { 433 SCIF_LOG_ERROR(( 434 sci_base_object_get_logger(fw_controller), 435 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION, 436 "Controller:0x%x Domain:0x%x Status:0x%x unable to start\n", 437 fw_controller, index, status 438 )); 439 440 return status; 441 } 442 443 // Attempt to start the core controller. 444 status = scic_controller_start(fw_controller->core_object, timeout); 445 if (status != SCI_SUCCESS) 446 { 447 SCIF_LOG_ERROR(( 448 sci_base_object_get_logger(fw_controller), 449 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION, 450 "Controller:0x%x Status:0x%x unable to start controller.\n", 451 fw_controller, status 452 )); 453 454 sci_base_state_machine_change_state( 455 &fw_controller->parent.state_machine, 456 SCI_BASE_CONTROLLER_STATE_FAILED 457 ); 458 } 459 460 return status; 461 } 462 463 //****************************************************************************** 464 //* R E A D Y H A N D L E R S 465 //****************************************************************************** 466 467 /** 468 * @brief This method provides READY state specific handling for 469 * when a user attempts to stop a controller. 470 * 471 * @param[in] controller This parameter specifies the controller object 472 * on which the user is attempting to perform a stop 473 * operation. 474 * @param[in] timeout This parameter specifies the timeout value (in 475 * milliseconds) to be utilized for this operation. 476 * 477 * @return This method returns an indication of whether the stop operation 478 * succeeded. 479 * @retval SCI_SUCCESS This value is returned when the stop operation 480 * begins successfully. 481 */ 482 static 483 SCI_STATUS scif_sas_controller_ready_stop_handler( 484 SCI_BASE_CONTROLLER_T * controller, 485 U32 timeout 486 ) 487 { 488 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)controller; 489 490 SCIF_LOG_TRACE(( 491 sci_base_object_get_logger(fw_controller), 492 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION, 493 "scif_sas_controller_ready_stop_handler(0x%x, 0x%x) enter\n", 494 controller, timeout 495 )); 496 497 sci_base_state_machine_change_state( 498 &fw_controller->parent.state_machine, 499 SCI_BASE_CONTROLLER_STATE_STOPPING 500 ); 501 502 if (fw_controller->user_parameters.sas.clear_affiliation_during_controller_stop) 503 { 504 fw_controller->current_domain_to_clear_affiliation = 0; 505 506 //clear affiliation first. After the last domain finishes clearing 507 //affiliation, it will call back to controller to continue to stop. 508 scif_sas_controller_clear_affiliation(fw_controller); 509 } 510 else 511 scif_sas_controller_continue_to_stop(fw_controller); 512 513 //Must return SUCCESS at this point. 514 return SCI_SUCCESS; 515 } 516 517 /** 518 * @brief This method provides READY state specific handling for 519 * when a user attempts to reset a controller. 520 * 521 * @param[in] controller This parameter specifies the controller object 522 * on which the user is attempting to perform a reset 523 * operation. 524 * 525 * @return This method returns an indication of whether the reset operation 526 * succeeded. 527 * @retval SCI_SUCCESS This value is returned when the reset operation 528 * completes successfully. 529 */ 530 static 531 SCI_STATUS scif_sas_controller_ready_reset_handler( 532 SCI_BASE_CONTROLLER_T * controller 533 ) 534 { 535 return scif_sas_controller_execute_reset((SCIF_SAS_CONTROLLER_T*)controller); 536 } 537 538 /** 539 * @brief This method provides READY state specific handling for 540 * when a user attempts to start an IO request. 541 * 542 * @param[in] controller This parameter specifies the controller object 543 * on which the user is attempting to perform a start IO 544 * operation. 545 * @param[in] remote_device This parameter specifies the remote deivce 546 * object on which the user is attempting to perform a start IO 547 * operation. 548 * @param[in] io_request This parameter specifies the IO request to be 549 * started. 550 * @param[in] io_tag This parameter specifies the optional allocated 551 * IO tag. Please reference scif_controller_start_io() for 552 * more information. 553 * 554 * @return This method returns an indication of whether the start IO 555 * operation succeeded. 556 * @retval SCI_SUCCESS This value is returned when the start IO operation 557 * begins successfully. 558 */ 559 static 560 SCI_STATUS scif_sas_controller_ready_start_io_handler( 561 SCI_BASE_CONTROLLER_T * controller, 562 SCI_BASE_REMOTE_DEVICE_T * remote_device, 563 SCI_BASE_REQUEST_T * io_request, 564 U16 io_tag 565 ) 566 { 567 SCI_STATUS status; 568 SCIF_SAS_IO_REQUEST_T *fw_io = (SCIF_SAS_IO_REQUEST_T*)io_request; 569 SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)controller; 570 SCIF_SAS_REMOTE_DEVICE_T *fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 571 remote_device; 572 573 SCIF_LOG_TRACE(( 574 sci_base_object_get_logger(fw_controller), 575 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 576 "scif_sas_controller_ready_start_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 577 controller, remote_device, io_request, io_tag 578 )); 579 580 status = fw_device->domain->state_handlers->start_io_handler( 581 &fw_device->domain->parent, remote_device, io_request 582 ); 583 584 // Check to see that the other objects in the framework allowed 585 // this IO to be started. 586 if (status == SCI_SUCCESS) 587 { 588 // Ask the core to start processing for this IO request. 589 status = (SCI_STATUS)scic_controller_start_io( 590 fw_controller->core_object, 591 fw_device->core_object, 592 fw_io->parent.core_object, 593 io_tag 594 ); 595 596 if (status == SCI_SUCCESS) 597 { 598 // We were able to start the core request. As a result, 599 // commit to starting the request for the framework by changing 600 // the state of the IO request. 601 sci_base_state_machine_change_state( 602 &io_request->state_machine, SCI_BASE_REQUEST_STATE_STARTED 603 ); 604 } 605 else 606 { 607 // We were unable to start the core IO request. As a result, 608 // back out the start operation for the framework. It's easier to 609 // back out the framework start operation then to backout the core 610 // start IO operation. 611 fw_device->domain->state_handlers->complete_io_handler( 612 &fw_device->domain->parent, remote_device, io_request 613 ); 614 615 // Invoke the IO completion handler. For most IOs, this does nothing 616 // since we are still in the constructed state. For NCQ, this will 617 // the return of the NCQ tag back to the remote device free pool. 618 fw_io->parent.state_handlers->complete_handler(io_request); 619 620 SCIF_LOG_WARNING(( 621 sci_base_object_get_logger(fw_controller), 622 SCIF_LOG_OBJECT_CONTROLLER, 623 "Controller:0x%x IORequest:0x%x Status:0x%x core IO start failed\n", 624 fw_controller, fw_io, status 625 )); 626 } 627 } 628 else 629 { 630 SCIF_LOG_WARNING(( 631 sci_base_object_get_logger(fw_controller), 632 SCIF_LOG_OBJECT_CONTROLLER, 633 "Controller:0x%x IORequest:0x%x Status:0x%x IO start failed\n", 634 fw_controller, fw_io, status 635 )); 636 } 637 638 return status; 639 } 640 641 /** 642 * @brief This method provides READY state specific handling for 643 * when a user attempts to complete an IO request. 644 * 645 * @param[in] controller This parameter specifies the controller object 646 * on which the user is attempting to perform a complete IO 647 * operation. 648 * @param[in] remote_device This parameter specifies the remote deivce 649 * object on which the user is attempting to perform a start IO 650 * operation. 651 * @param[in] io_request This parameter specifies the IO request to be 652 * started. 653 * 654 * @return This method returns an indication of whether the complete IO 655 * operation succeeded. 656 * @retval SCI_SUCCESS This value is returned when the complete IO operation 657 * begins successfully. 658 */ 659 static 660 SCI_STATUS scif_sas_controller_ready_complete_io_handler( 661 SCI_BASE_CONTROLLER_T * controller, 662 SCI_BASE_REMOTE_DEVICE_T * remote_device, 663 SCI_BASE_REQUEST_T * io_request 664 ) 665 { 666 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) 667 controller; 668 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 669 remote_device; 670 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 671 io_request; 672 SCI_STATUS status; 673 SCI_STATUS core_status; 674 675 SCIF_LOG_TRACE(( 676 sci_base_object_get_logger(fw_controller), 677 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 678 "scif_sas_controller_ready_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n", 679 controller, remote_device, io_request 680 )); 681 682 fw_io->parent.state_handlers->destruct_handler(&fw_io->parent.parent); 683 status = fw_device->domain->state_handlers->complete_io_handler( 684 &fw_device->domain->parent, remote_device, io_request 685 ); 686 687 // Ask the core to finish processing for this IO request. 688 core_status = scic_controller_complete_io( 689 fw_controller->core_object, 690 fw_device->core_object, 691 fw_io->parent.core_object 692 ); 693 694 if (status == SCI_SUCCESS) 695 status = core_status; 696 697 if (status != SCI_SUCCESS) 698 { 699 SCIF_LOG_WARNING(( 700 sci_base_object_get_logger(fw_controller), 701 SCIF_LOG_OBJECT_CONTROLLER, 702 "Controller:0x%x IORequest:0x%x Status:0x%x CoreStatus:0x%x " 703 "failure to complete IO\n", 704 fw_controller, fw_io, status, core_status 705 )); 706 } 707 708 return status; 709 } 710 711 712 /** 713 * @brief This method provides READY state specific handling for 714 * when a user attempts to complete a high priority IO request. 715 * 716 * @param[in] controller This parameter specifies the controller object 717 * on which the user is attempting to perform a complete IO 718 * operation. 719 * @param[in] remote_device This parameter specifies the remote deivce 720 * object on which the user is attempting to perform a start IO 721 * operation. 722 * @param[in] io_request This parameter specifies the IO request to be 723 * started. 724 * 725 * @return This method returns an indication of whether the complete IO 726 * operation succeeded. 727 * @retval SCI_SUCCESS This value is returned when the complete IO operation 728 * begins successfully. 729 */ 730 static 731 SCI_STATUS scif_sas_controller_ready_complete_high_priority_io_handler( 732 SCI_BASE_CONTROLLER_T * controller, 733 SCI_BASE_REMOTE_DEVICE_T * remote_device, 734 SCI_BASE_REQUEST_T * io_request 735 ) 736 { 737 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) 738 controller; 739 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 740 remote_device; 741 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 742 io_request; 743 SCI_IO_STATUS core_completion_status = 744 scic_request_get_sci_status(fw_io->parent.core_object); 745 746 U8 response_data[SCIF_SAS_RESPONSE_DATA_LENGTH]; 747 748 SCI_STATUS status; 749 SCI_STATUS core_status; 750 751 SCIF_LOG_TRACE(( 752 sci_base_object_get_logger(fw_controller), 753 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 754 "scif_sas_controller_ready_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x) enter\n", 755 controller, remote_device, io_request 756 )); 757 758 // In high priority path, we ask the core to finish IO request before framework. 759 760 // retrieve and save io response from core now. 761 memcpy(response_data, 762 scic_io_request_get_response_iu_address(fw_io->parent.core_object), 763 SCIF_SAS_RESPONSE_DATA_LENGTH 764 ); 765 766 core_status = scic_controller_complete_io( 767 fw_controller->core_object, 768 fw_device->core_object, 769 fw_io->parent.core_object 770 ); 771 772 fw_io->parent.state_handlers->destruct_handler(&fw_io->parent.parent); 773 status = fw_device->domain->state_handlers->complete_high_priority_io_handler( 774 &fw_device->domain->parent, 775 remote_device, 776 io_request, 777 (void *)response_data, 778 core_completion_status 779 ); 780 781 if (status == SCI_SUCCESS) 782 status = core_status; 783 784 if (status == SCI_SUCCESS) 785 { 786 //issue DPC to start next internal io in high prioriy queue. 787 if( !sci_pool_empty(fw_controller->hprq.pool) ) 788 scif_cb_start_internal_io_task_schedule( 789 fw_controller, 790 scif_sas_controller_start_high_priority_io, 791 fw_controller 792 ); 793 } 794 else 795 { 796 SCIF_LOG_WARNING(( 797 sci_base_object_get_logger(fw_controller), 798 SCIF_LOG_OBJECT_CONTROLLER, 799 "Controller:0x%x IORequest:0x%x Status:0x%x CoreStatus:0x%x " 800 "failure to complete IO\n", 801 fw_controller, fw_io, status, core_status 802 )); 803 } 804 805 return status; 806 } 807 808 /** 809 * @brief This method provides READY state specific handling for 810 * when a user attempts to continue an IO request. 811 * 812 * @param[in] controller This parameter specifies the controller object 813 * on which the user is attempting to perform a continue IO 814 * operation. 815 * @param[in] remote_device This parameter specifies the remote deivce 816 * object on which the user is attempting to perform a start IO 817 * operation. 818 * @param[in] io_request This parameter specifies the IO request to be 819 * started. 820 * 821 * @return This method returns an indication of whether the continue IO 822 * operation succeeded. 823 * @retval SCI_SUCCESS This value is returned when the continue IO operation 824 * begins successfully. 825 */ 826 static 827 SCI_STATUS scif_sas_controller_ready_continue_io_handler( 828 SCI_BASE_CONTROLLER_T * controller, 829 SCI_BASE_REMOTE_DEVICE_T * remote_device, 830 SCI_BASE_REQUEST_T * io_request 831 ) 832 { 833 SCIF_LOG_TRACE(( 834 sci_base_object_get_logger(controller), 835 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 836 "scif_sas_controller_ready_continue_io_handler(0x%x, 0x%x, 0x%x) enter\n", 837 controller, remote_device, io_request 838 )); 839 840 /// @todo Function unimplemented. fix return code handling. 841 return SCI_FAILURE; 842 } 843 844 /** 845 * @brief This method provides READY state specific handling for 846 * when a user attempts to start a task request. 847 * 848 * @param[in] controller This parameter specifies the controller object 849 * on which the user is attempting to perform a start task 850 * operation. 851 * @param[in] remote_device This parameter specifies the remote deivce 852 * object on which the user is attempting to perform a start 853 * task operation. 854 * @param[in] task_request This parameter specifies the task management 855 * request to be started. 856 * @param[in] io_tag This parameter specifies the optional allocated 857 * IO tag. Please reference scif_controller_start_task() for 858 * more information. 859 * 860 * @return This method returns an indication of whether the start task 861 * operation succeeded. 862 * @retval SCI_SUCCESS This value is returned when the start task operation 863 * begins successfully. 864 */ 865 static 866 SCI_STATUS scif_sas_controller_ready_start_task_handler( 867 SCI_BASE_CONTROLLER_T * controller, 868 SCI_BASE_REMOTE_DEVICE_T * remote_device, 869 SCI_BASE_REQUEST_T * task_request, 870 U16 io_tag 871 ) 872 { 873 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) 874 controller; 875 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 876 remote_device; 877 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*)task_request; 878 SCI_STATUS status; 879 880 SCIF_LOG_TRACE(( 881 sci_base_object_get_logger(fw_controller), 882 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 883 "scif_sas_controller_ready_start_task_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 884 controller, remote_device, task_request, io_tag 885 )); 886 887 status = fw_device->domain->state_handlers->start_task_handler( 888 &fw_device->domain->parent, remote_device, task_request 889 ); 890 891 if (status == SCI_SUCCESS) 892 { 893 if (scif_sas_task_request_get_function(fw_task) 894 == SCI_SAS_HARD_RESET) 895 { 896 // Go off to special target reset path. Don't start task to core. 897 scif_sas_remote_device_target_reset( 898 fw_device, 899 (SCIF_SAS_REQUEST_T *)fw_task 900 ); 901 902 return SCI_SUCCESS; 903 } 904 905 // Ask the core to start processing for this task request. 906 status = (SCI_STATUS)scic_controller_start_task( 907 fw_controller->core_object, 908 fw_device->core_object, 909 fw_task->parent.core_object, 910 io_tag 911 ); 912 913 if (status == SCI_SUCCESS) 914 { 915 // We were able to start the core request. As a result, 916 // commit to starting the request for the framework by changing 917 // the state of the task request. 918 fw_task->parent.state_handlers->start_handler(&fw_task->parent.parent); 919 } 920 else 921 { 922 // We were unable to start the core task request. As a result, 923 // back out the start operation for the framework. It's easier to 924 // back out the framework start operation then to backout the core 925 // start task operation. 926 fw_device->domain->state_handlers->complete_task_handler( 927 &fw_device->domain->parent, remote_device, task_request 928 ); 929 930 if (status == SCI_SUCCESS) 931 { 932 SCIF_LOG_WARNING(( 933 sci_base_object_get_logger(fw_controller), 934 SCIF_LOG_OBJECT_CONTROLLER, 935 "Controller:0x%x TaskRequest:0x%x Status:0x%x core start failed\n", 936 fw_controller, fw_task, status 937 )); 938 } 939 } 940 } 941 else 942 { 943 SCIF_LOG_WARNING(( 944 sci_base_object_get_logger(fw_controller), 945 SCIF_LOG_OBJECT_CONTROLLER, 946 "Controller:0x%x TaskRequest:0x%x Status:0x%x Task start failed\n", 947 fw_controller, fw_task, status 948 )); 949 } 950 951 return status; 952 } 953 954 /** 955 * @brief This method provides READY state specific handling for 956 * when a user attempts to complete a task request. 957 * 958 * @param[in] controller This parameter specifies the controller object 959 * on which the user is attempting to perform a complete task 960 * operation. 961 * @param[in] remote_device This parameter specifies the remote deivce 962 * object on which the user is attempting to perform a start 963 * task operation. 964 * @param[in] task_request This parameter specifies the task management 965 * request to be started. 966 * 967 * @return This method returns an indication of whether the complete task 968 * operation succeeded. 969 * @retval SCI_SUCCESS This value is returned when the complete task operation 970 * begins successfully. 971 */ 972 static 973 SCI_STATUS scif_sas_controller_ready_complete_task_handler( 974 SCI_BASE_CONTROLLER_T * controller, 975 SCI_BASE_REMOTE_DEVICE_T * remote_device, 976 SCI_BASE_REQUEST_T * task_request 977 ) 978 { 979 SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)controller; 980 SCIF_SAS_REMOTE_DEVICE_T *fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)remote_device; 981 SCIF_SAS_TASK_REQUEST_T *fw_task = (SCIF_SAS_TASK_REQUEST_T*)task_request; 982 SCI_STATUS status; 983 SCI_STATUS core_status; 984 985 SCIF_LOG_TRACE(( 986 sci_base_object_get_logger(fw_controller), 987 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 988 "scif_sas_controller_ready_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n", 989 controller, remote_device, task_request 990 )); 991 992 status = fw_device->domain->state_handlers->complete_task_handler( 993 &fw_device->domain->parent, remote_device, task_request 994 ); 995 996 if (scif_sas_task_request_get_function(fw_task) 997 == SCI_SAS_HARD_RESET) 998 { 999 //No more things to do in the core, since this task is for Target Reset. 1000 return status; 1001 } 1002 1003 fw_task->parent.state_handlers->destruct_handler(&fw_task->parent.parent); 1004 1005 // Ask the core to finish processing for this task request. 1006 core_status = scic_controller_complete_task( 1007 fw_controller->core_object, 1008 fw_device->core_object, 1009 fw_task->parent.core_object 1010 ); 1011 1012 if (status == SCI_SUCCESS) 1013 status = core_status; 1014 1015 if (status != SCI_SUCCESS) 1016 { 1017 SCIF_LOG_WARNING(( 1018 sci_base_object_get_logger(fw_controller), 1019 SCIF_LOG_OBJECT_CONTROLLER, 1020 "Controller:0x%x TaskRequest:0x%x Status:0x%x CoreStatus:0x%x " 1021 "failed to complete\n", 1022 fw_controller, fw_task, status, core_status 1023 )); 1024 } 1025 1026 return status; 1027 } 1028 1029 1030 1031 /** 1032 * @brief This method provides common handling for several states 1033 * when a user attempts to start an internal request. 1034 * 1035 * @param[in] controller This parameter specifies the controller object 1036 * on which the user is attempting to perform a start IO 1037 * operation. 1038 * @param[in] remote_device This parameter specifies the remote deivce 1039 * object on which the user is attempting to perform a start IO 1040 * operation. 1041 * @param[in] io_request This parameter specifies the IO request to be 1042 * started. 1043 * @param[in] io_tag This parameter specifies the optional allocated 1044 * IO tag. Please reference scif_controller_start_io() for 1045 * more information. 1046 * 1047 * @return This method returns an indication of whether the start IO 1048 * operation succeeded. 1049 * @retval SCI_SUCCESS This value is returned when the start IO operation 1050 * begins successfully. 1051 */ 1052 static 1053 SCI_STATUS scif_sas_controller_common_start_high_priority_io_handler( 1054 SCI_BASE_CONTROLLER_T * controller, 1055 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1056 SCI_BASE_REQUEST_T * io_request, 1057 U16 io_tag 1058 ) 1059 { 1060 SCI_STATUS status; 1061 SCIF_SAS_IO_REQUEST_T *fw_io = (SCIF_SAS_IO_REQUEST_T*)io_request; 1062 SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)controller; 1063 SCIF_SAS_REMOTE_DEVICE_T *fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 1064 remote_device; 1065 1066 status = fw_device->domain->state_handlers->start_high_priority_io_handler( 1067 &fw_device->domain->parent, remote_device, io_request 1068 ); 1069 1070 // Check to see that the other objects in the framework allowed 1071 // this IO to be started. 1072 if (status == SCI_SUCCESS) 1073 { 1074 // Ask the core to start processing for this IO request. 1075 status = (SCI_STATUS)scic_controller_start_io( 1076 fw_controller->core_object, 1077 fw_device->core_object, 1078 fw_io->parent.core_object, 1079 io_tag 1080 ); 1081 1082 if (status == SCI_SUCCESS) 1083 { 1084 // We were able to start the core request. As a result, 1085 // commit to starting the request for the framework by changing 1086 // the state of the IO request. 1087 sci_base_state_machine_change_state( 1088 &io_request->state_machine, SCI_BASE_REQUEST_STATE_STARTED 1089 ); 1090 } 1091 else 1092 { 1093 // We were unable to start the core IO request. As a result, 1094 // back out the start operation for the framework. It's easier to 1095 // back out the framework start operation then to backout the core 1096 // start IO operation. 1097 fw_device->domain->state_handlers->complete_io_handler( 1098 &fw_device->domain->parent, remote_device, io_request 1099 ); 1100 1101 // Invoke the IO completion handler. For most IOs, this does nothing 1102 // since we are still in the constructed state. For NCQ, this will 1103 // the return of the NCQ tag back to the remote device free pool. 1104 fw_io->parent.state_handlers->complete_handler(io_request); 1105 1106 SCIF_LOG_WARNING(( 1107 sci_base_object_get_logger(fw_controller), 1108 SCIF_LOG_OBJECT_CONTROLLER, 1109 "Controller:0x%x IORequest:0x%x Status:0x%x core IO start failed\n", 1110 fw_controller, fw_io, status 1111 )); 1112 } 1113 } 1114 else 1115 { 1116 SCIF_LOG_WARNING(( 1117 sci_base_object_get_logger(fw_controller), 1118 SCIF_LOG_OBJECT_CONTROLLER, 1119 "Controller:0x%x IORequest:0x%x Status:0x%x IO start failed\n", 1120 fw_controller, fw_io, status 1121 )); 1122 1123 // Invoke the IO completion handler. For most IOs, this does nothing 1124 // since we are still in the constructed state. For NCQ, this will 1125 // the return of the NCQ tag back to the remote device free pool. 1126 fw_io->parent.state_handlers->complete_handler(io_request); 1127 1128 } 1129 1130 if (fw_io->parent.is_internal && status != SCI_SUCCESS ) 1131 { 1132 SCIC_TRANSPORT_PROTOCOL protocol = 1133 scic_io_request_get_protocol(fw_io->parent.core_object); 1134 1135 U8 retry_count = fw_io->retry_count; 1136 1137 scif_sas_internal_io_request_destruct( 1138 fw_device->domain->controller, 1139 (SCIF_SAS_INTERNAL_IO_REQUEST_T *)fw_io 1140 ); 1141 1142 if ( protocol == SCIC_SMP_PROTOCOL ) 1143 { 1144 if (fw_device->protocol_device.smp_device.smp_activity_timer != NULL) 1145 { 1146 //destroy the smp_activity_timer 1147 scif_cb_timer_destroy ( 1148 fw_controller, 1149 fw_device->protocol_device.smp_device.smp_activity_timer 1150 ); 1151 1152 fw_device->protocol_device.smp_device.smp_activity_timer = NULL; 1153 } 1154 1155 //we should retry for finite times 1156 if ( retry_count < SCIF_SAS_IO_RETRY_LIMIT) 1157 { 1158 //An internal smp request failed being started, most likely due to remote device 1159 //is not in ready state, for example, UPDATING_PORT_WIDTH state. In this case, 1160 //we should retry the IO. 1161 scif_sas_smp_remote_device_retry_internal_io( 1162 (SCIF_SAS_REMOTE_DEVICE_T *)remote_device, 1163 retry_count, 1164 SMP_REQUEST_RETRY_WAIT_DURATION 1165 ); 1166 } 1167 } 1168 } 1169 1170 return status; 1171 } 1172 1173 1174 /** 1175 * @brief This method provides READY state specific handling for 1176 * when a user attempts to start an internal request. If the high 1177 * priority IO is also internal, this method will schedule its timer. 1178 * 1179 * @param[in] controller This parameter specifies the controller object 1180 * on which the user is attempting to perform a start IO 1181 * operation. 1182 * @param[in] remote_device This parameter specifies the remote deivce 1183 * object on which the user is attempting to perform a start IO 1184 * operation. 1185 * @param[in] io_request This parameter specifies the IO request to be 1186 * started. 1187 * @param[in] io_tag This parameter specifies the optional allocated 1188 * IO tag. Please reference scif_controller_start_io() for 1189 * more information. 1190 * 1191 * @return This method returns an indication of whether the start IO 1192 * operation succeeded. 1193 * @retval SCI_SUCCESS This value is returned when the start IO operation 1194 * begins successfully. 1195 */ 1196 static 1197 SCI_STATUS scif_sas_controller_ready_start_high_priority_io_handler( 1198 SCI_BASE_CONTROLLER_T * controller, 1199 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1200 SCI_BASE_REQUEST_T * io_request, 1201 U16 io_tag 1202 ) 1203 { 1204 SCI_STATUS status; 1205 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *)io_request; 1206 1207 SCIF_LOG_TRACE(( 1208 sci_base_object_get_logger(controller), 1209 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 1210 "scif_sas_controller_ready_start_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 1211 controller, remote_device, io_request, io_tag 1212 )); 1213 1214 status = scif_sas_controller_common_start_high_priority_io_handler( 1215 controller, remote_device, io_request, io_tag); 1216 1217 if (status == SCI_SUCCESS) 1218 { 1219 //External io could also be put in high priority queue. i.e. the 1220 //smp request for EA Target Reset. 1221 if (fw_io->parent.is_internal) 1222 { 1223 SCIF_SAS_INTERNAL_IO_REQUEST_T * fw_internal_io = 1224 (SCIF_SAS_INTERNAL_IO_REQUEST_T *)fw_io; 1225 1226 //start the timer for internal io 1227 scif_cb_timer_start( 1228 (SCI_CONTROLLER_HANDLE_T)controller, 1229 fw_internal_io->internal_io_timer, 1230 SCIF_SAS_INTERNAL_REQUEST_TIMEOUT 1231 ); 1232 } 1233 } 1234 else 1235 { 1236 //If failed to start, most likely the device or domain is not in 1237 //correct state, and the IO has been cleaned up in controller's start 1238 //high priority IO handler. We should just continue to start the next 1239 //IO in the HP queue. 1240 1241 SCIF_LOG_TRACE(( 1242 sci_base_object_get_logger(controller), 1243 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 1244 "scif_controller_start_high_priority_io(0x%x, 0x%x), starting io failed\n", 1245 controller, fw_io 1246 )); 1247 } 1248 1249 return status; 1250 } 1251 1252 1253 //****************************************************************************** 1254 //* S T O P P I N G H A N D L E R S 1255 //****************************************************************************** 1256 /** 1257 * @brief This method provides STOPPING state specific handling for 1258 * when a user attempts to start an internal request. Note that we don't 1259 * start the timer for internal IO during controller stopping state. 1260 * 1261 * @param[in] controller This parameter specifies the controller object 1262 * on which the user is attempting to perform a start IO 1263 * operation. 1264 * @param[in] remote_device This parameter specifies the remote deivce 1265 * object on which the user is attempting to perform a start IO 1266 * operation. 1267 * @param[in] io_request This parameter specifies the IO request to be 1268 * started. 1269 * @param[in] io_tag This parameter specifies the optional allocated 1270 * IO tag. Please reference scif_controller_start_io() for 1271 * more information. 1272 * 1273 * @return This method returns an indication of whether the start IO 1274 * operation succeeded. 1275 * @retval SCI_SUCCESS This value is returned when the start IO operation 1276 * begins successfully. 1277 */ 1278 static 1279 SCI_STATUS scif_sas_controller_stopping_start_high_priority_io_handler( 1280 SCI_BASE_CONTROLLER_T * controller, 1281 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1282 SCI_BASE_REQUEST_T * io_request, 1283 U16 io_tag 1284 ) 1285 { 1286 SCIF_LOG_TRACE(( 1287 sci_base_object_get_logger(controller), 1288 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 1289 "scif_sas_controller_stopping_start_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 1290 controller, remote_device, io_request, io_tag 1291 )); 1292 1293 return scif_sas_controller_common_start_high_priority_io_handler( 1294 controller, remote_device, io_request, io_tag); 1295 } 1296 1297 1298 //****************************************************************************** 1299 //* S T O P P E D H A N D L E R S 1300 //****************************************************************************** 1301 1302 /** 1303 * @brief This method provides STOPPED state specific handling for 1304 * when a user attempts to reset a controller. 1305 * 1306 * @param[in] controller This parameter specifies the controller object 1307 * on which the user is attempting to perform a reset 1308 * operation. 1309 * 1310 * @return This method returns an indication of whether the reset operation 1311 * succeeded. 1312 * @retval SCI_SUCCESS This value is returned when the reset operation 1313 * completes successfully. 1314 */ 1315 static 1316 SCI_STATUS scif_sas_controller_stopped_reset_handler( 1317 SCI_BASE_CONTROLLER_T * controller 1318 ) 1319 { 1320 return scif_sas_controller_execute_reset((SCIF_SAS_CONTROLLER_T*)controller); 1321 } 1322 1323 1324 //****************************************************************************** 1325 //* F A I L E D H A N D L E R S 1326 //****************************************************************************** 1327 1328 /** 1329 * @brief This method provides FAILED state specific handling for 1330 * when a user attempts to reset a controller. 1331 * 1332 * @param[in] controller This parameter specifies the controller object 1333 * on which the user is attempting to perform a reset 1334 * operation. 1335 * 1336 * @return This method returns an indication of whether the reset operation 1337 * succeeded. 1338 * @retval SCI_SUCCESS This value is returned when the reset operation 1339 * completes successfully. 1340 */ 1341 static 1342 SCI_STATUS scif_sas_controller_failed_reset_handler( 1343 SCI_BASE_CONTROLLER_T * controller 1344 ) 1345 { 1346 return scif_sas_controller_execute_reset((SCIF_SAS_CONTROLLER_T*)controller); 1347 } 1348 1349 //****************************************************************************** 1350 //* D E F A U L T H A N D L E R S 1351 //****************************************************************************** 1352 1353 /** 1354 * @brief This method provides default handling (i.e. returns an error) 1355 * when a user attempts to start a controller and a start operation 1356 * is not allowed. 1357 * 1358 * @param[in] controller This parameter specifies the controller object 1359 * on which the user is attempting to perform a start operation. 1360 * @param[in] timeout This parameter specifies the timeout value (in 1361 * milliseconds) to be utilized for this operation. 1362 * 1363 * @return This method returns an indication that start operations are not 1364 * allowed. 1365 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1366 */ 1367 static 1368 SCI_STATUS scif_sas_controller_default_start_handler( 1369 SCI_BASE_CONTROLLER_T * controller, 1370 U32 timeout 1371 ) 1372 { 1373 SCIF_LOG_WARNING(( 1374 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller), 1375 SCIF_LOG_OBJECT_CONTROLLER, 1376 "Controller:0x%x State:0x%x invalid state to start controller.\n", 1377 controller, 1378 sci_base_state_machine_get_state( 1379 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine) 1380 )); 1381 1382 return SCI_FAILURE_INVALID_STATE; 1383 } 1384 1385 /** 1386 * @brief This method provides default handling (i.e. returns an error) 1387 * when a user attempts to stop a controller and a stop operation 1388 * is not allowed. 1389 * 1390 * @param[in] controller This parameter specifies the controller object 1391 * on which the user is attempting to perform a stop operation. 1392 * @param[in] timeout This parameter specifies the timeout value (in 1393 * milliseconds) to be utilized for this operation. 1394 * 1395 * @return This method returns an indication that stop operations are not 1396 * allowed. 1397 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1398 */ 1399 static 1400 SCI_STATUS scif_sas_controller_default_stop_handler( 1401 SCI_BASE_CONTROLLER_T * controller, 1402 U32 timeout 1403 ) 1404 { 1405 SCIF_LOG_WARNING(( 1406 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller), 1407 SCIF_LOG_OBJECT_CONTROLLER, 1408 "Controller:0x%x State:0x%x invalid state to stop controller.\n", 1409 controller, 1410 sci_base_state_machine_get_state( 1411 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine) 1412 )); 1413 1414 return SCI_FAILURE_INVALID_STATE; 1415 } 1416 1417 /** 1418 * @brief This method provides default handling (i.e. returns an error) 1419 * when a user attempts to reset a controller and a reset operation 1420 * is not allowed. 1421 * 1422 * @param[in] controller This parameter specifies the controller object 1423 * on which the user is attempting to perform a reset operation. 1424 * 1425 * @return This method returns an indication that reset operations are not 1426 * allowed. 1427 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1428 */ 1429 static 1430 SCI_STATUS scif_sas_controller_default_reset_handler( 1431 SCI_BASE_CONTROLLER_T * controller 1432 ) 1433 { 1434 SCIF_LOG_WARNING(( 1435 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller), 1436 SCIF_LOG_OBJECT_CONTROLLER, 1437 "Controller:0x%x State:0x%x invalid state to reset controller.\n", 1438 controller, 1439 sci_base_state_machine_get_state( 1440 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine) 1441 )); 1442 1443 return SCI_FAILURE_INVALID_STATE; 1444 } 1445 1446 /** 1447 * @brief This method provides default handling (i.e. returns an error) 1448 * when a user attempts to initialize a controller and an initialize 1449 * operation is not allowed. 1450 * 1451 * @param[in] controller This parameter specifies the controller object 1452 * on which the user is attempting to perform an initialize 1453 * operation. 1454 * 1455 * @return This method returns an indication that initialize operations 1456 * are not allowed. 1457 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1458 */ 1459 static 1460 SCI_STATUS scif_sas_controller_default_initialize_handler( 1461 SCI_BASE_CONTROLLER_T * controller 1462 ) 1463 { 1464 SCIF_LOG_WARNING(( 1465 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller), 1466 SCIF_LOG_OBJECT_CONTROLLER, 1467 "Controller:0x%x State:0x%x invalid state to initialize controller.\n", 1468 controller, 1469 sci_base_state_machine_get_state( 1470 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine) 1471 )); 1472 1473 return SCI_FAILURE_INVALID_STATE; 1474 } 1475 1476 /** 1477 * @brief This method provides default handling (i.e. returns an error) 1478 * when a user attempts to start an IO on a controller and a start 1479 * IO operation is not allowed. 1480 * 1481 * @param[in] controller This parameter specifies the controller object 1482 * on which the user is attempting to perform a start IO 1483 * operation. 1484 * @param[in] remote_device This parameter specifies the remote deivce 1485 * object on which the user is attempting to perform a start IO 1486 * operation. 1487 * @param[in] io_request This parameter specifies the IO request to be 1488 * started. 1489 * @param[in] io_tag This parameter specifies the optional allocated 1490 * IO tag. Please reference scif_controller_start_io() for 1491 * more information. 1492 * 1493 * @return This method returns an indication that start IO operations 1494 * are not allowed. 1495 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1496 */ 1497 static 1498 SCI_STATUS scif_sas_controller_default_start_io_handler( 1499 SCI_BASE_CONTROLLER_T * controller, 1500 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1501 SCI_BASE_REQUEST_T * io_request, 1502 U16 io_tag 1503 ) 1504 { 1505 SCIF_LOG_WARNING(( 1506 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller), 1507 SCIF_LOG_OBJECT_CONTROLLER, 1508 "Controller:0x%x State:0x%x invalid state to start IO.\n", 1509 controller, 1510 sci_base_state_machine_get_state( 1511 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine) 1512 )); 1513 1514 return SCI_FAILURE_INVALID_STATE; 1515 } 1516 1517 /** 1518 * @brief This method provides default handling (i.e. returns an error) 1519 * when a user attempts to complete an IO on a controller and a 1520 * complete IO operation is not allowed. 1521 * 1522 * @param[in] controller This parameter specifies the controller object 1523 * on which the user is attempting to perform a complete IO 1524 * operation. 1525 * @param[in] remote_device This parameter specifies the remote deivce 1526 * object on which the user is attempting to perform a start IO 1527 * operation. 1528 * @param[in] io_request This parameter specifies the IO request to be 1529 * started. 1530 * 1531 * @return This method returns an indication that complete IO operations 1532 * are not allowed. 1533 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1534 */ 1535 static 1536 SCI_STATUS scif_sas_controller_default_complete_io_handler( 1537 SCI_BASE_CONTROLLER_T * controller, 1538 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1539 SCI_BASE_REQUEST_T * io_request 1540 ) 1541 { 1542 SCIF_LOG_WARNING(( 1543 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller), 1544 SCIF_LOG_OBJECT_CONTROLLER, 1545 "Controller:0x%x State:0x%x invalid state to complete IO.\n", 1546 controller, 1547 sci_base_state_machine_get_state( 1548 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine) 1549 )); 1550 1551 return SCI_FAILURE_INVALID_STATE; 1552 } 1553 1554 /** 1555 * @brief This method provides default handling (i.e. returns an error) 1556 * when a user attempts to continue an IO on a controller and a 1557 * continue IO operation is not allowed. 1558 * 1559 * @param[in] controller This parameter specifies the controller object 1560 * on which the user is attempting to perform a continue IO 1561 * operation. 1562 * @param[in] remote_device This parameter specifies the remote deivce 1563 * object on which the user is attempting to perform a start IO 1564 * operation. 1565 * @param[in] io_request This parameter specifies the IO request to be 1566 * started. 1567 * 1568 * @return This method returns an indication that continue IO operations 1569 * are not allowed. 1570 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1571 */ 1572 static 1573 SCI_STATUS scif_sas_controller_default_continue_io_handler( 1574 SCI_BASE_CONTROLLER_T * controller, 1575 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1576 SCI_BASE_REQUEST_T * io_request 1577 ) 1578 { 1579 SCIF_LOG_WARNING(( 1580 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller), 1581 SCIF_LOG_OBJECT_CONTROLLER, 1582 "Controller:0x%x State:0x%x invalid state to continue IO.\n", 1583 controller, 1584 sci_base_state_machine_get_state( 1585 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine) 1586 )); 1587 1588 return SCI_FAILURE_INVALID_STATE; 1589 } 1590 1591 /** 1592 * @brief This method provides default handling (i.e. returns an error) 1593 * when a user attempts to start a task on a controller and a start 1594 * task operation is not allowed. 1595 * 1596 * @param[in] controller This parameter specifies the controller object 1597 * on which the user is attempting to perform a start task 1598 * operation. 1599 * @param[in] remote_device This parameter specifies the remote deivce 1600 * object on which the user is attempting to perform a start 1601 * task operation. 1602 * @param[in] task_request This parameter specifies the task management 1603 * request to be started. 1604 * @param[in] io_tag This parameter specifies the optional allocated 1605 * IO tag. Please reference scif_controller_start_task() for 1606 * more information. 1607 * 1608 * @return This method returns an indication that start task operations 1609 * are not allowed. 1610 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1611 */ 1612 static 1613 SCI_STATUS scif_sas_controller_default_start_task_handler( 1614 SCI_BASE_CONTROLLER_T * controller, 1615 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1616 SCI_BASE_REQUEST_T * task_request, 1617 U16 io_tag 1618 ) 1619 { 1620 SCIF_LOG_WARNING(( 1621 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller), 1622 SCIF_LOG_OBJECT_CONTROLLER, 1623 "Controller:0x%x State:0x%x invalid state to start task mgmt.\n", 1624 controller, 1625 sci_base_state_machine_get_state( 1626 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine) 1627 )); 1628 1629 return SCI_FAILURE_INVALID_STATE; 1630 } 1631 1632 /** 1633 * @brief This method provides default handling (i.e. returns an error) 1634 * when a user attempts to complete a task on a controller and a 1635 * complete task operation is not allowed. 1636 * 1637 * @param[in] controller This parameter specifies the controller object 1638 * on which the user is attempting to perform a complete task 1639 * operation. 1640 * @param[in] remote_device This parameter specifies the remote deivce 1641 * object on which the user is attempting to perform a start 1642 * task operation. 1643 * @param[in] task_request This parameter specifies the task management 1644 * request to be started. 1645 * 1646 * @return This method returns an indication that complete task operations 1647 * are not allowed. 1648 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1649 */ 1650 static 1651 SCI_STATUS scif_sas_controller_default_complete_task_handler( 1652 SCI_BASE_CONTROLLER_T * controller, 1653 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1654 SCI_BASE_REQUEST_T * task_request 1655 ) 1656 { 1657 SCIF_LOG_WARNING(( 1658 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller), 1659 SCIF_LOG_OBJECT_CONTROLLER, 1660 "Controller:0x%x State:0x%x invalid state to complete task mgmt.\n", 1661 controller, 1662 sci_base_state_machine_get_state( 1663 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine) 1664 )); 1665 1666 return SCI_FAILURE_INVALID_STATE; 1667 } 1668 1669 static 1670 SCI_STATUS scif_sas_controller_failed_state_start_io_handler( 1671 SCI_BASE_CONTROLLER_T * controller, 1672 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1673 SCI_BASE_REQUEST_T * io_request, 1674 U16 io_tag 1675 ) 1676 { 1677 SCIF_LOG_WARNING(( 1678 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller), 1679 SCIF_LOG_OBJECT_CONTROLLER, 1680 "Controller:0x%x State:0x%x invalid state to start IO.\n", 1681 controller, 1682 sci_base_state_machine_get_state( 1683 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine) 1684 )); 1685 1686 return SCI_FAILURE; 1687 } 1688 1689 #define scif_sas_controller_stopping_complete_io_handler \ 1690 scif_sas_controller_ready_complete_io_handler 1691 #define scif_sas_controller_stopping_complete_task_handler \ 1692 scif_sas_controller_ready_complete_task_handler 1693 #define scif_sas_controller_default_start_high_priority_io_handler \ 1694 scif_sas_controller_default_start_io_handler 1695 #define scif_sas_controller_default_complete_high_priority_io_handler \ 1696 scif_sas_controller_default_complete_io_handler 1697 #define scif_sas_controller_stopping_complete_high_priority_io_handler \ 1698 scif_sas_controller_ready_complete_high_priority_io_handler 1699 1700 1701 SCI_BASE_CONTROLLER_STATE_HANDLER_T 1702 scif_sas_controller_state_handler_table[SCI_BASE_CONTROLLER_MAX_STATES] = 1703 { 1704 // SCI_BASE_CONTROLLER_STATE_INITIAL 1705 { 1706 scif_sas_controller_default_start_handler, 1707 scif_sas_controller_default_stop_handler, 1708 scif_sas_controller_default_reset_handler, 1709 scif_sas_controller_default_initialize_handler, 1710 scif_sas_controller_default_start_io_handler, 1711 scif_sas_controller_default_start_high_priority_io_handler, 1712 scif_sas_controller_default_complete_io_handler, 1713 scif_sas_controller_default_complete_high_priority_io_handler, 1714 scif_sas_controller_default_continue_io_handler, 1715 scif_sas_controller_default_start_task_handler, 1716 scif_sas_controller_default_complete_task_handler 1717 }, 1718 // SCI_BASE_CONTROLLER_STATE_RESET 1719 { 1720 scif_sas_controller_default_start_handler, 1721 scif_sas_controller_default_stop_handler, 1722 scif_sas_controller_default_reset_handler, 1723 scif_sas_controller_reset_initialize_handler, 1724 scif_sas_controller_default_start_io_handler, 1725 scif_sas_controller_default_start_high_priority_io_handler, 1726 scif_sas_controller_default_complete_io_handler, 1727 scif_sas_controller_default_complete_high_priority_io_handler, 1728 scif_sas_controller_default_continue_io_handler, 1729 scif_sas_controller_default_start_task_handler, 1730 scif_sas_controller_default_complete_task_handler 1731 }, 1732 // SCI_BASE_CONTROLLER_STATE_INITIALIZING 1733 { 1734 scif_sas_controller_default_start_handler, 1735 scif_sas_controller_default_stop_handler, 1736 scif_sas_controller_default_reset_handler, 1737 scif_sas_controller_default_initialize_handler, 1738 scif_sas_controller_default_start_io_handler, 1739 scif_sas_controller_default_start_high_priority_io_handler, 1740 scif_sas_controller_default_complete_io_handler, 1741 scif_sas_controller_default_complete_high_priority_io_handler, 1742 scif_sas_controller_default_continue_io_handler, 1743 scif_sas_controller_default_start_task_handler, 1744 scif_sas_controller_default_complete_task_handler 1745 }, 1746 // SCI_BASE_CONTROLLER_STATE_INITIALIZED 1747 { 1748 scif_sas_controller_initialized_start_handler, 1749 scif_sas_controller_default_stop_handler, 1750 scif_sas_controller_default_reset_handler, 1751 scif_sas_controller_default_initialize_handler, 1752 scif_sas_controller_default_start_io_handler, 1753 scif_sas_controller_default_start_high_priority_io_handler, 1754 scif_sas_controller_default_complete_io_handler, 1755 scif_sas_controller_default_complete_high_priority_io_handler, 1756 scif_sas_controller_default_continue_io_handler, 1757 scif_sas_controller_default_start_task_handler, 1758 scif_sas_controller_default_complete_task_handler 1759 }, 1760 // SCI_BASE_CONTROLLER_STATE_STARTING 1761 { 1762 scif_sas_controller_default_start_handler, 1763 scif_sas_controller_default_stop_handler, 1764 scif_sas_controller_default_reset_handler, 1765 scif_sas_controller_default_initialize_handler, 1766 scif_sas_controller_default_start_io_handler, 1767 scif_sas_controller_default_start_high_priority_io_handler, 1768 scif_sas_controller_default_complete_io_handler, 1769 scif_sas_controller_default_complete_high_priority_io_handler, 1770 scif_sas_controller_default_continue_io_handler, 1771 scif_sas_controller_default_start_task_handler, 1772 scif_sas_controller_default_complete_task_handler 1773 }, 1774 // SCI_BASE_CONTROLLER_STATE_READY 1775 { 1776 scif_sas_controller_default_start_handler, 1777 scif_sas_controller_ready_stop_handler, 1778 scif_sas_controller_ready_reset_handler, 1779 scif_sas_controller_default_initialize_handler, 1780 scif_sas_controller_ready_start_io_handler, 1781 scif_sas_controller_ready_start_high_priority_io_handler, 1782 scif_sas_controller_ready_complete_io_handler, 1783 scif_sas_controller_ready_complete_high_priority_io_handler, 1784 scif_sas_controller_ready_continue_io_handler, 1785 scif_sas_controller_ready_start_task_handler, 1786 scif_sas_controller_ready_complete_task_handler 1787 }, 1788 // SCI_BASE_CONTROLLER_STATE_RESETTING 1789 { 1790 scif_sas_controller_default_start_handler, 1791 scif_sas_controller_default_stop_handler, 1792 scif_sas_controller_default_reset_handler, 1793 scif_sas_controller_default_initialize_handler, 1794 scif_sas_controller_default_start_io_handler, 1795 scif_sas_controller_default_start_high_priority_io_handler, 1796 scif_sas_controller_default_complete_io_handler, 1797 scif_sas_controller_default_complete_high_priority_io_handler, 1798 scif_sas_controller_default_continue_io_handler, 1799 scif_sas_controller_default_start_task_handler, 1800 scif_sas_controller_default_complete_task_handler 1801 }, 1802 // SCI_BASE_CONTROLLER_STATE_STOPPING 1803 { 1804 scif_sas_controller_default_start_handler, 1805 scif_sas_controller_default_stop_handler, 1806 scif_sas_controller_default_reset_handler, 1807 scif_sas_controller_default_initialize_handler, 1808 scif_sas_controller_default_start_io_handler, 1809 scif_sas_controller_stopping_start_high_priority_io_handler, 1810 scif_sas_controller_stopping_complete_io_handler, 1811 scif_sas_controller_stopping_complete_high_priority_io_handler, 1812 scif_sas_controller_default_continue_io_handler, 1813 scif_sas_controller_default_start_task_handler, /**@todo Allow in core?*/ 1814 scif_sas_controller_stopping_complete_task_handler 1815 }, 1816 // SCI_BASE_CONTROLLER_STATE_STOPPED 1817 { 1818 scif_sas_controller_default_start_handler, 1819 scif_sas_controller_default_stop_handler, 1820 scif_sas_controller_stopped_reset_handler, 1821 scif_sas_controller_default_initialize_handler, 1822 scif_sas_controller_default_start_io_handler, 1823 scif_sas_controller_default_start_high_priority_io_handler, 1824 scif_sas_controller_default_complete_io_handler, 1825 scif_sas_controller_default_complete_high_priority_io_handler, 1826 scif_sas_controller_default_continue_io_handler, 1827 scif_sas_controller_default_start_task_handler, 1828 scif_sas_controller_default_complete_task_handler 1829 }, 1830 // SCI_BASE_CONTROLLER_STATE_FAILED 1831 { 1832 scif_sas_controller_default_start_handler, 1833 scif_sas_controller_default_stop_handler, 1834 scif_sas_controller_failed_reset_handler, 1835 scif_sas_controller_default_initialize_handler, 1836 scif_sas_controller_failed_state_start_io_handler, 1837 scif_sas_controller_failed_state_start_io_handler, 1838 scif_sas_controller_default_complete_io_handler, 1839 scif_sas_controller_default_complete_high_priority_io_handler, 1840 scif_sas_controller_default_continue_io_handler, 1841 scif_sas_controller_default_start_task_handler, 1842 scif_sas_controller_default_complete_task_handler 1843 } 1844 }; 1845 1846