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