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 method implementations pertaining 62 * to the framework remote device state handler methods. 63 */ 64 65#include <dev/isci/scil/scic_remote_device.h> 66 67#include <dev/isci/scil/scif_sas_logger.h> 68#include <dev/isci/scil/scif_sas_remote_device.h> 69#include <dev/isci/scil/scif_sas_domain.h> 70#include <dev/isci/scil/scif_sas_task_request.h> 71#include <dev/isci/scil/scif_sas_internal_io_request.h> 72 73//****************************************************************************** 74//* S T O P P E D H A N D L E R S 75//****************************************************************************** 76 77/** 78 * @brief This method provides STOPPED state specific handling for 79 * when the framework attempts to start the remote device. This 80 * method attempts to transition the state machine into the 81 * STARTING state. If this is unsuccessful, then there is a direct 82 * transition into the FAILED state. 83 * 84 * @param[in] remote_device This parameter specifies the remote device 85 * object for which the framework is attempting to start. 86 * 87 * @return This method returns an indication as to whether the start 88 * operating began successfully. 89 */ 90static 91SCI_STATUS scif_sas_remote_device_stopped_start_handler( 92 SCI_BASE_REMOTE_DEVICE_T * remote_device 93) 94{ 95 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) 96 remote_device; 97 98 sci_base_state_machine_change_state( 99 &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STARTING 100 ); 101 102 // Check to see if the state transition occurred without issue. 103 if (sci_base_state_machine_get_state(&fw_device->parent.state_machine) 104 == SCI_BASE_REMOTE_DEVICE_STATE_FAILED) 105 { 106 SCIF_LOG_WARNING(( 107 sci_base_object_get_logger(fw_device), 108 SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 109 "Domain:0x%x Device:0x%x Status:0x%x failed to start\n", 110 fw_device->domain, fw_device, fw_device->operation_status 111 )); 112 } 113 114 return fw_device->operation_status; 115} 116 117/** 118 * @brief This method provides STOPPED state specific handling for 119 * when the user attempts to destruct the remote device. 120 * 121 * @param[in] remote_device This parameter specifies the remote device 122 * object for which the framework is attempting to start. 123 * 124 * @return This method returns an indication as to whether the destruct 125 * operation completed successfully. 126 */ 127static 128SCI_STATUS scif_sas_remote_device_stopped_destruct_handler( 129 SCI_BASE_REMOTE_DEVICE_T * remote_device 130) 131{ 132 SCI_STATUS status; 133 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) 134 remote_device; 135 136 SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; 137 scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); 138 139 //For smp device, need to clear its smp phy list first. 140 if(dev_protocols.u.bits.attached_smp_target) 141 scif_sas_smp_remote_device_removed(fw_device); 142 143 status = scic_remote_device_destruct(fw_device->core_object); 144 if (status == SCI_SUCCESS) 145 { 146 sci_base_state_machine_change_state( 147 &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_FINAL 148 ); 149 150 scif_sas_remote_device_deinitialize_state_logging(fw_device); 151 } 152 else 153 { 154 SCIF_LOG_ERROR(( 155 sci_base_object_get_logger(fw_device), 156 SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG, 157 "Device:0x%x Status:0x%x failed to destruct core device\n", 158 fw_device 159 )); 160 } 161 162 return status; 163} 164 165//****************************************************************************** 166//* S T O P P I N G H A N D L E R S 167//****************************************************************************** 168 169/** 170 * @brief This method provides STOPPING state specific handling for 171 * when the core remote device object issues a stop completion 172 * notification. 173 * 174 * @note There is no need to ensure all IO/Task requests are complete 175 * before transitioning to the STOPPED state. The SCI Core will 176 * ensure this is accomplished. 177 * 178 * @param[in] remote_device This parameter specifies the remote device 179 * object for which the completion occurred. 180 * @param[in] completion_status This parameter specifies the status 181 * of the completion operation. 182 * 183 * @return none. 184 */ 185static 186void scif_sas_remote_device_stopping_stop_complete_handler( 187 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 188 SCI_STATUS completion_status 189) 190{ 191 // Transition directly to the STOPPED state since the core ensures 192 // all IO/Tasks are complete. 193 sci_base_state_machine_change_state( 194 &fw_device->parent.state_machine, 195 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED 196 ); 197 198 if (completion_status != SCI_SUCCESS) 199 { 200 SCIF_LOG_ERROR(( 201 sci_base_object_get_logger(fw_device), 202 SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG, 203 "Device:0x%x Status:0x%x failed to stop core device\n", 204 fw_device, completion_status 205 )); 206 207 // Something is seriously wrong. Stopping the core remote device 208 // shouldn't fail in anyway. 209 scif_cb_controller_error(fw_device->domain->controller, 210 SCI_CONTROLLER_REMOTE_DEVICE_ERROR); 211 } 212} 213 214/** 215 * @brief This method provides STOPPING state handling for high priority 216 * IO requests, when the framework attempts to complete a high 217 * priority request. 218 * 219 * @param[in] remote_device This parameter specifies the remote device 220 * object for which to complete the high priority IO. 221 * @param[in] io_request This parameter specifies the IO request to be 222 * completed. 223 * @param[in] response_data This parameter is ignored, since the device 224 * is in the stopping state. 225 * 226 * @return This method always returns success. 227 */ 228static 229SCI_STATUS scif_sas_remote_device_stopping_complete_high_priority_io_handler( 230 SCI_BASE_REMOTE_DEVICE_T * remote_device, 231 SCI_BASE_REQUEST_T * io_request, 232 void * response_data, 233 SCI_IO_STATUS completion_status 234) 235{ 236 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) 237 remote_device; 238 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T *) io_request; 239 240 SCIF_LOG_TRACE(( 241 sci_base_object_get_logger(remote_device), 242 SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_IO_REQUEST, 243 "scif_sas_remote_device_stopping_complete_high_priority_io_handler(0x%x,0x%x,0x%x) enter\n", 244 remote_device, io_request, response_data 245 )); 246 247 fw_device->request_count--; 248 249 if (fw_request->is_internal == TRUE) 250 { 251 scif_sas_internal_io_request_complete( 252 fw_device->domain->controller, 253 (SCIF_SAS_INTERNAL_IO_REQUEST_T *) io_request, 254 SCI_SUCCESS 255 ); 256 } 257 258 return SCI_SUCCESS; 259} 260 261//****************************************************************************** 262//* F A I L E D H A N D L E R S 263//****************************************************************************** 264 265/** 266 * @brief This method provides FAILED state specific handling for 267 * when the remote device is being stopped by the framework. 268 * 269 * @param[in] remote_device This parameter specifies the remote device 270 * object for which the stop operation is being requested. 271 * 272 * @return This method returns an indication as to whether the failure 273 * operation completed successfully. 274 */ 275static 276SCI_STATUS scif_sas_remote_device_failed_stop_handler( 277 SCI_BASE_REMOTE_DEVICE_T * remote_device 278) 279{ 280 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) 281 remote_device; 282 283 SCIF_LOG_WARNING(( 284 sci_base_object_get_logger(fw_device), 285 SCIF_LOG_OBJECT_REMOTE_DEVICE, 286 "RemoteDevice:0x%x stopping failed device\n", 287 fw_device 288 )); 289 290 sci_base_state_machine_change_state( 291 &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 292 ); 293 294 /// @todo Fix the return code handling. 295 return SCI_FAILURE; 296} 297 298//****************************************************************************** 299//* D E F A U L T H A N D L E R S 300//****************************************************************************** 301 302/** 303 * @brief This method provides default handling (i.e. returns an error); 304 * when a user attempts to start a remote device and a start operation 305 * is not allowed. 306 * 307 * @param[in] remote_device This parameter specifies the remote device object 308 * on which the user is attempting to perform a start operation. 309 * 310 * @return This method returns an indication that start operations are not 311 * allowed. 312 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 313 */ 314SCI_STATUS scif_sas_remote_device_default_start_handler( 315 SCI_BASE_REMOTE_DEVICE_T * remote_device 316) 317{ 318 SCIF_LOG_WARNING(( 319 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 320 SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG, 321 "RemoteDevice:0x%x State:0x%x invalid state to start\n", 322 remote_device, 323 sci_base_state_machine_get_state( 324 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 325 )); 326 327 return SCI_FAILURE_INVALID_STATE; 328} 329 330/** 331 * @brief This method provides default handling (i.e. returns an error); 332 * when a user attempts to stop a remote device and a stop operation 333 * is not allowed. 334 * 335 * @param[in] remote_device This parameter specifies the remote device object 336 * on which the user is attempting to perform a stop operation. 337 * 338 * @return This method returns an indication that stop operations are not 339 * allowed. 340 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 341 */ 342SCI_STATUS scif_sas_remote_device_default_stop_handler( 343 SCI_BASE_REMOTE_DEVICE_T * remote_device 344) 345{ 346 SCIF_LOG_WARNING(( 347 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 348 SCIF_LOG_OBJECT_REMOTE_DEVICE, 349 "RemoteDevice:0x%x State:0x%x invalid state to stop\n", 350 remote_device, 351 sci_base_state_machine_get_state( 352 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 353 )); 354 355 return SCI_FAILURE_INVALID_STATE; 356} 357 358/** 359 * @brief This method provides default handling (i.e. returns an error); 360 * when there is an attempt to fail a remote device from an invalid 361 * state. 362 * 363 * @param[in] remote_device This parameter specifies the remote device 364 * object on which there is an attempt to fail the device. 365 * 366 * @return This method returns an indication that the fail transition is not 367 * allowed. 368 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 369 */ 370static 371SCI_STATUS scif_sas_remote_device_default_fail_handler( 372 SCI_BASE_REMOTE_DEVICE_T * remote_device 373) 374{ 375 SCIF_LOG_WARNING(( 376 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 377 SCIF_LOG_OBJECT_REMOTE_DEVICE, 378 "RemoteDevice:0x%x State:0x%x invalid state to fail device\n", 379 remote_device, 380 sci_base_state_machine_get_state( 381 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 382 )); 383 384 return SCI_FAILURE_INVALID_STATE; 385} 386 387/** 388 * @brief This method provides default handling (i.e. returns an error); 389 * when there is an attempt to destruct a remote device from an 390 * invalid state. 391 * 392 * @param[in] remote_device This parameter specifies the remote device 393 * object on which there is an attempt to fail the device. 394 * 395 * @return This method returns an indication that the fail transition is not 396 * allowed. 397 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 398 */ 399SCI_STATUS scif_sas_remote_device_default_destruct_handler( 400 SCI_BASE_REMOTE_DEVICE_T * remote_device 401) 402{ 403 SCIF_LOG_WARNING(( 404 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 405 SCIF_LOG_OBJECT_REMOTE_DEVICE, 406 "RemoteDevice:0x%x State:0x%x invalid state to destruct.\n", 407 remote_device, 408 sci_base_state_machine_get_state( 409 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 410 )); 411 412 return SCI_FAILURE_INVALID_STATE; 413} 414 415/** 416 * @brief This method provides default handling (i.e. returns an error); 417 * when there is an attempt to reset a remote device from an invalid 418 * state. 419 * 420 * @param[in] remote_device This parameter specifies the remote device 421 * object on which there is an attempt to fail the device. 422 * 423 * @return This method returns an indication that the fail transition is not 424 * allowed. 425 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 426 */ 427SCI_STATUS scif_sas_remote_device_default_reset_handler( 428 SCI_BASE_REMOTE_DEVICE_T * remote_device 429) 430{ 431 SCIF_LOG_WARNING(( 432 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 433 SCIF_LOG_OBJECT_REMOTE_DEVICE, 434 "RemoteDevice:0x%x State:0x%x invalid state to reset.\n", 435 remote_device, 436 sci_base_state_machine_get_state( 437 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 438 )); 439 440 return SCI_FAILURE_INVALID_STATE; 441} 442 443/** 444 * @brief This method provides default handling (i.e. returns an error); 445 * when there is an attempt to complete a reset to the remote device 446 * from an invalid state. 447 * 448 * @param[in] remote_device This parameter specifies the remote device 449 * object on which there is an attempt to fail the device. 450 * 451 * @return This method returns an indication that the fail transition is not 452 * allowed. 453 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 454 */ 455SCI_STATUS scif_sas_remote_device_default_reset_complete_handler( 456 SCI_BASE_REMOTE_DEVICE_T * remote_device 457) 458{ 459 SCIF_LOG_WARNING(( 460 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 461 SCIF_LOG_OBJECT_REMOTE_DEVICE, 462 "RemoteDevice:0x%x State:0x%x invalid state to complete reset.\n", 463 remote_device, 464 sci_base_state_machine_get_state( 465 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 466 )); 467 468 return SCI_FAILURE_INVALID_STATE; 469} 470 471/** 472 * @brief This method provides default handling (i.e. returns an error); 473 * when a user attempts to start an IO on a remote device and a start 474 * IO operation is not allowed. 475 * 476 * @param[in] remote_device This parameter specifies the remote device 477 * object on which the user is attempting to perform a start IO 478 * operation. 479 * @param[in] io_request This parameter specifies the IO request to be 480 * started. 481 * 482 * @return This method returns an indication that start IO operations 483 * are not allowed. 484 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 485 */ 486SCI_STATUS scif_sas_remote_device_default_start_io_handler( 487 SCI_BASE_REMOTE_DEVICE_T * remote_device, 488 SCI_BASE_REQUEST_T * io_request 489) 490{ 491 SCIF_LOG_WARNING(( 492 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 493 SCIF_LOG_OBJECT_REMOTE_DEVICE, 494 "RemoteDevice:0x%x State:0x%x invalid state to start IO.\n", 495 remote_device, 496 sci_base_state_machine_get_state( 497 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 498 )); 499 500 return SCI_FAILURE_INVALID_STATE; 501} 502 503/** 504 * @brief This method provides default handling (i.e. returns an error); 505 * when a user attempts to complete an IO on a remote device and a 506 * complete IO operation is not allowed. 507 * 508 * @param[in] remote_device This parameter specifies the remote device 509 * object on which the user is attempting to perform a complete 510 * IO operation. 511 * @param[in] io_request This parameter specifies the IO request to be 512 * completed. 513 * 514 * @return This method returns an indication that complete IO operations 515 * are not allowed. 516 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 517 */ 518SCI_STATUS scif_sas_remote_device_default_complete_io_handler( 519 SCI_BASE_REMOTE_DEVICE_T * remote_device, 520 SCI_BASE_REQUEST_T * io_request 521) 522{ 523 SCIF_LOG_WARNING(( 524 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 525 SCIF_LOG_OBJECT_REMOTE_DEVICE, 526 "RemoteDevice:0x%x State:0x%x invalid state to complete IO\n", 527 remote_device, 528 sci_base_state_machine_get_state( 529 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 530 )); 531 532 return SCI_FAILURE_INVALID_STATE; 533} 534 535 536/** 537 * @brief This method provides default handling (i.e. returns an error); 538 * when a user attempts to complete an IO on a remote device and a 539 * complete IO operation is not allowed. 540 * 541 * @param[in] remote_device This parameter specifies the remote device 542 * object on which the user is attempting to perform a start IO 543 * operation. 544 * @param[in] io_request This parameter specifies the IO request to be 545 * started. 546 * 547 * @return This method returns an indication that complete IO operations 548 * are not allowed. 549 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 550 */ 551SCI_STATUS scif_sas_remote_device_default_complete_high_priority_io_handler( 552 SCI_BASE_REMOTE_DEVICE_T * remote_device, 553 SCI_BASE_REQUEST_T * io_request, 554 void * response_data, 555 SCI_IO_STATUS completion_status 556) 557{ 558 SCIF_LOG_WARNING(( 559 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 560 SCIF_LOG_OBJECT_REMOTE_DEVICE, 561 "RemoteDevice:0x%x State:0x%x invalid state to complete high priority IO\n", 562 remote_device, 563 sci_base_state_machine_get_state( 564 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 565 )); 566 567 return SCI_FAILURE_INVALID_STATE; 568} 569 570 571/** 572 * @brief This method provides default handling (i.e. returns an error); 573 * when a user attempts to continue an IO on a remote device and a 574 * continue IO operation is not allowed. 575 * 576 * @param[in] remote_device This parameter specifies the remote device 577 * object on which the user is attempting to perform a start IO 578 * operation. 579 * @param[in] io_request This parameter specifies the IO request to be 580 * started. 581 * 582 * @return This method returns an indication that continue IO operations 583 * are not allowed. 584 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 585 */ 586SCI_STATUS scif_sas_remote_device_default_continue_io_handler( 587 SCI_BASE_REMOTE_DEVICE_T * remote_device, 588 SCI_BASE_REQUEST_T * io_request 589) 590{ 591 SCIF_LOG_WARNING(( 592 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 593 SCIF_LOG_OBJECT_REMOTE_DEVICE, 594 "RemoteDevice:0x%x State:0x%x invalid state to continue IO\n", 595 remote_device, 596 sci_base_state_machine_get_state( 597 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 598 )); 599 600 return SCI_FAILURE_INVALID_STATE; 601} 602 603/** 604 * @brief This method provides default handling (i.e. returns an error); 605 * when a user attempts to start a task on a remote device and a 606 * start task operation is not allowed. 607 * 608 * @param[in] remote_device This parameter specifies the remote device 609 * object on which the user is attempting to perform a start 610 * task operation. 611 * @param[in] task_request This parameter specifies the task management 612 * request to be started. 613 * 614 * @return This method returns an indication that start task operations 615 * are not allowed. 616 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 617 */ 618SCI_STATUS scif_sas_remote_device_default_start_task_handler( 619 SCI_BASE_REMOTE_DEVICE_T * remote_device, 620 SCI_BASE_REQUEST_T * task_request 621) 622{ 623 SCIF_LOG_WARNING(( 624 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 625 SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 626 "RemoteDevice:0x%x State:0x%x invalid state to start task\n", 627 remote_device, 628 sci_base_state_machine_get_state( 629 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 630 )); 631 632 return SCI_FAILURE_INVALID_STATE; 633} 634 635/** 636 * @brief This method provides default handling (i.e. returns an error); 637 * when a user attempts to complete a task on a remote device and a 638 * complete task operation is not allowed. 639 * 640 * @param[in] remote_device This parameter specifies the remote device object 641 * on which the user is attempting to perform a complete task 642 * operation. 643 * @param[in] task_request This parameter specifies the task management 644 * request to be completed. 645 * 646 * @return This method returns an indication that complete task operations 647 * are not allowed. 648 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 649 */ 650SCI_STATUS scif_sas_remote_device_default_complete_task_handler( 651 SCI_BASE_REMOTE_DEVICE_T * remote_device, 652 SCI_BASE_REQUEST_T * task_request 653) 654{ 655 SCIF_LOG_WARNING(( 656 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 657 SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 658 "RemoteDevice:0x%x State:0x%x invalid state to complete task\n", 659 remote_device, 660 sci_base_state_machine_get_state( 661 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 662 )); 663 664 return SCI_FAILURE_INVALID_STATE; 665} 666 667/** 668 * @brief This method provides default handling (i.e. returns an error); 669 * for when the core issues a start completion notification and 670 * such a notification isn't supported. 671 * 672 * @param[in] remote_device This parameter specifies the remote device object 673 * for which the completion notification has occurred. 674 * @param[in] completion_status This parameter specifies the status 675 * of the completion operation. 676 * 677 * @return none. 678 */ 679void scif_sas_remote_device_default_start_complete_handler( 680 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 681 SCI_STATUS completion_status 682) 683{ 684 SCIF_LOG_WARNING(( 685 sci_base_object_get_logger(fw_device), 686 SCIF_LOG_OBJECT_REMOTE_DEVICE, 687 "RemoteDevice:0x%x State:0x%x invalid state to start complete\n", 688 fw_device, 689 sci_base_state_machine_get_state(&fw_device->parent.state_machine) 690 )); 691} 692 693/** 694 * @brief This method provides default handling (i.e. returns an error); 695 * for when the core issues a stop completion notification and 696 * such a notification isn't supported. 697 * 698 * @param[in] remote_device This parameter specifies the remote device object 699 * for which the completion notification has occurred. 700 * @param[in] completion_status This parameter specifies the status 701 * of the completion operation. 702 * 703 * @return none. 704 */ 705void scif_sas_remote_device_default_stop_complete_handler( 706 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 707 SCI_STATUS completion_status 708) 709{ 710 SCIF_LOG_WARNING(( 711 sci_base_object_get_logger(fw_device), 712 SCIF_LOG_OBJECT_REMOTE_DEVICE, 713 "RemoteDevice:0x%x State:0x%x invalid state to stop complete\n", 714 fw_device, 715 sci_base_state_machine_get_state(&fw_device->parent.state_machine) 716 )); 717} 718 719/** 720 * @brief This method provides default handling (i.e. returns an error); 721 * for when the core issues a ready notification and such a 722 * notification isn't supported. 723 * 724 * @param[in] remote_device This parameter specifies the remote device object 725 * for which the notification has occurred. 726 * 727 * @return none. 728 */ 729void scif_sas_remote_device_default_ready_handler( 730 SCIF_SAS_REMOTE_DEVICE_T * fw_device 731) 732{ 733 SCIF_LOG_WARNING(( 734 sci_base_object_get_logger(fw_device), 735 SCIF_LOG_OBJECT_REMOTE_DEVICE, 736 "RemoteDevice:0x%x State:0x%x invalid state to handle ready\n", 737 fw_device, 738 sci_base_state_machine_get_state(&fw_device->parent.state_machine) 739 )); 740} 741 742/** 743 * @brief This method provides default handling (i.e. returns an error); 744 * for when the core issues a not ready notification and such a 745 * notification isn't supported. 746 * 747 * @param[in] remote_device This parameter specifies the remote device object 748 * for which the notification has occurred. 749 * 750 * @return none. 751 */ 752void scif_sas_remote_device_default_not_ready_handler( 753 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 754 U32 reason_code 755) 756{ 757 SCIF_LOG_WARNING(( 758 sci_base_object_get_logger(fw_device), 759 SCIF_LOG_OBJECT_REMOTE_DEVICE, 760 "RemoteDevice:0x%x State:0x%x invalid state to handle not ready\n", 761 fw_device, 762 sci_base_state_machine_get_state(&fw_device->parent.state_machine) 763 )); 764} 765 766#if !defined(DISABLE_WIDE_PORTED_TARGETS) 767/** 768 * @brief This method provides handling of device start complete duing 769 * UPDATING_PORT_WIDTH state. 770 * 771 * @param[in] remote_device This parameter specifies the remote device object 772 * which is start complete. 773 * 774 * @return none. 775 */ 776static 777SCI_STATUS scif_sas_remote_device_updating_port_width_state_complete_io_handler( 778 SCI_BASE_REMOTE_DEVICE_T * remote_device, 779 SCI_BASE_REQUEST_T * io_request 780) 781{ 782 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 783 remote_device; 784 fw_device->request_count--; 785 786 //If the request count is zero, go ahead to update the RNC. 787 if (fw_device->request_count == 0 ) 788 { 789 if (fw_device->destination_state == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING) 790 { 791 //if the destination state of this device change to STOPPING, no matter 792 //whether we need to update the port width, just make the device 793 //go to the STOPPING state, the device will be removed anyway. 794 sci_base_state_machine_change_state( 795 &fw_device->parent.state_machine, 796 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 797 ); 798 } 799 else 800 { 801 //stop the device, upon the stop complete callback, start the device again 802 //with the updated port width. 803 scic_remote_device_stop( 804 fw_device->core_object, SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT); 805 } 806 } 807 808 return SCI_SUCCESS; 809} 810 811 812/** 813 * @brief This method provides handling of device start complete duing 814 * UPDATING_PORT_WIDTH state. 815 * 816 * @param[in] remote_device This parameter specifies the remote device object 817 * which is start complete. 818 * 819 * @return none. 820 */ 821static 822void scif_sas_remote_device_updating_port_width_state_start_complete_handler( 823 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 824 SCI_STATUS completion_status 825) 826{ 827 SCIF_LOG_INFO(( 828 sci_base_object_get_logger(fw_device), 829 SCIF_LOG_OBJECT_REMOTE_DEVICE, 830 "RemoteDevice:0x%x updating port width state start complete handler\n", 831 fw_device, 832 sci_base_state_machine_get_state(&fw_device->parent.state_machine) 833 )); 834 835 if ( fw_device->destination_state 836 == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING ) 837 { 838 //if the destination state of this device change to STOPPING, no matter 839 //whether we need to update the port width again, just make the device 840 //go to the STOPPING state. 841 sci_base_state_machine_change_state( 842 &fw_device->parent.state_machine, 843 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 844 ); 845 } 846 else if ( scic_remote_device_get_port_width(fw_device->core_object) 847 != fw_device->device_port_width 848 && fw_device->device_port_width != 0) 849 { 850 scic_remote_device_stop( 851 fw_device->core_object, 852 SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT 853 ); 854 } 855 else 856 { 857 //Port width updating succeeds. Transfer to destination state. 858 sci_base_state_machine_change_state( 859 &fw_device->parent.state_machine, 860 SCI_BASE_REMOTE_DEVICE_STATE_READY 861 ); 862 } 863} 864 865/** 866 * @brief This method provides handling of device stop complete duing 867 * UPDATING_PORT_WIDTH state. 868 * 869 * @param[in] remote_device This parameter specifies the remote device object 870 * which is stop complete. 871 * 872 * @return none. 873 */ 874static 875void scif_sas_remote_device_updating_port_width_state_stop_complete_handler( 876 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 877 SCI_STATUS completion_status 878) 879{ 880 SCIF_LOG_INFO(( 881 sci_base_object_get_logger(fw_device), 882 SCIF_LOG_OBJECT_REMOTE_DEVICE, 883 "RemoteDevice:0x%x updating port width state stop complete handler\n", 884 fw_device, 885 sci_base_state_machine_get_state(&fw_device->parent.state_machine) 886 )); 887 888 if ( fw_device->destination_state 889 == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING ) 890 { 891 //Device directly transits to STOPPED STATE from UPDATING_PORT_WIDTH state, 892 fw_device->domain->device_start_count--; 893 894 //if the destination state of this device change to STOPPING, no matter 895 //whether we need to update the port width again, just make the device 896 //go to the STOPPED state. 897 sci_base_state_machine_change_state( 898 &fw_device->parent.state_machine, 899 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED 900 ); 901 } 902 else 903 { 904 scic_remote_device_set_port_width( 905 fw_device->core_object, 906 fw_device->device_port_width 907 ); 908 909 //Device stop complete, means the RNC has been destructed. Now we need to 910 //start core device so the RNC with updated port width will be posted. 911 scic_remote_device_start( 912 fw_device->core_object, SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT); 913 } 914} 915 916/** 917 * @brief This method provides handling (i.e. returns an error); 918 * when a user attempts to stop a remote device during the updating 919 * port width state, it will record the destination state for this 920 * device to be STOPPING, instead of usually READY state. 921 * 922 * @param[in] remote_device This parameter specifies the remote device object 923 * on which the user is attempting to perform a stop operation. 924 * 925 * @return This method always return SCI_SUCCESS. 926 */ 927static 928SCI_STATUS scif_sas_remote_device_updating_port_width_state_stop_handler( 929 SCI_BASE_REMOTE_DEVICE_T * remote_device 930) 931{ 932 SCIF_SAS_REMOTE_DEVICE_T * fw_device = 933 (SCIF_SAS_REMOTE_DEVICE_T *)remote_device; 934 935 SCIF_LOG_INFO(( 936 sci_base_object_get_logger(fw_device), 937 SCIF_LOG_OBJECT_REMOTE_DEVICE, 938 "RemoteDevice:0x%x updating port width state stop handler\n", 939 fw_device, 940 sci_base_state_machine_get_state(&fw_device->parent.state_machine) 941 )); 942 943 //Can't stop the device right now. Remember the pending stopping request. 944 //When exit the UPDATING_PORT_WIDTH state, we will check this variable 945 //to decide which state to go. 946 fw_device->destination_state = 947 SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING; 948 949 return SCI_SUCCESS; 950} 951 952#endif //#if !defined(DISABLE_WIDE_PORTED_TARGETS) 953 954#define scif_sas_remote_device_stopping_complete_io_handler \ 955 scif_sas_remote_device_ready_operational_complete_io_handler 956#define scif_sas_remote_device_stopping_complete_task_handler \ 957 scif_sas_remote_device_ready_operational_complete_task_handler 958 959SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T 960scif_sas_remote_device_state_handler_table[SCI_BASE_REMOTE_DEVICE_MAX_STATES] = 961{ 962 // SCI_BASE_REMOTE_DEVICE_STATE_INITIAL 963 { 964 { 965 scif_sas_remote_device_default_start_handler, 966 scif_sas_remote_device_default_stop_handler, 967 scif_sas_remote_device_default_fail_handler, 968 scif_sas_remote_device_default_destruct_handler, 969 scif_sas_remote_device_default_reset_handler, 970 scif_sas_remote_device_default_reset_complete_handler, 971 scif_sas_remote_device_default_start_io_handler, 972 scif_sas_remote_device_default_complete_io_handler, 973 scif_sas_remote_device_default_continue_io_handler, 974 scif_sas_remote_device_default_start_task_handler, 975 scif_sas_remote_device_default_complete_task_handler 976 }, 977 scif_sas_remote_device_default_start_complete_handler, 978 scif_sas_remote_device_default_stop_complete_handler, 979 scif_sas_remote_device_default_ready_handler, 980 scif_sas_remote_device_default_not_ready_handler, 981 scif_sas_remote_device_default_start_io_handler, 982 scif_sas_remote_device_default_complete_high_priority_io_handler 983 }, 984 // SCI_BASE_REMOTE_DEVICE_STATE_STOPPED 985 { 986 { 987 scif_sas_remote_device_stopped_start_handler, 988 scif_sas_remote_device_default_stop_handler, 989 scif_sas_remote_device_default_fail_handler, 990 scif_sas_remote_device_stopped_destruct_handler, 991 scif_sas_remote_device_default_reset_handler, 992 scif_sas_remote_device_default_reset_complete_handler, 993 scif_sas_remote_device_default_start_io_handler, 994 scif_sas_remote_device_default_complete_io_handler, 995 scif_sas_remote_device_default_continue_io_handler, 996 scif_sas_remote_device_default_start_task_handler, 997 scif_sas_remote_device_default_complete_task_handler 998 }, 999 scif_sas_remote_device_default_start_complete_handler, 1000 scif_sas_remote_device_default_stop_complete_handler, 1001 scif_sas_remote_device_default_ready_handler, 1002 scif_sas_remote_device_default_not_ready_handler, 1003 scif_sas_remote_device_default_start_io_handler, 1004 scif_sas_remote_device_default_complete_high_priority_io_handler 1005 }, 1006 // SCI_BASE_REMOTE_DEVICE_STATE_STARTING 1007 { 1008 { 1009 scif_sas_remote_device_default_start_handler, 1010 scif_sas_remote_device_default_stop_handler, 1011 scif_sas_remote_device_default_fail_handler, 1012 scif_sas_remote_device_default_destruct_handler, 1013 scif_sas_remote_device_default_reset_handler, 1014 scif_sas_remote_device_default_reset_complete_handler, 1015 scif_sas_remote_device_default_start_io_handler, 1016 scif_sas_remote_device_default_complete_io_handler, 1017 scif_sas_remote_device_default_continue_io_handler, 1018 scif_sas_remote_device_default_start_task_handler, 1019 scif_sas_remote_device_default_complete_task_handler 1020 }, 1021 scif_sas_remote_device_default_start_complete_handler, 1022 scif_sas_remote_device_default_stop_complete_handler, 1023 scif_sas_remote_device_default_ready_handler, 1024 scif_sas_remote_device_default_not_ready_handler, 1025 scif_sas_remote_device_default_start_io_handler, 1026 scif_sas_remote_device_default_complete_high_priority_io_handler 1027 }, 1028 // SCI_BASE_REMOTE_DEVICE_STATE_READY - see substate handlers 1029 { 1030 { 1031 scif_sas_remote_device_default_start_handler, 1032 scif_sas_remote_device_default_stop_handler, 1033 scif_sas_remote_device_default_fail_handler, 1034 scif_sas_remote_device_default_destruct_handler, 1035 scif_sas_remote_device_default_reset_handler, 1036 scif_sas_remote_device_default_reset_complete_handler, 1037 scif_sas_remote_device_default_start_io_handler, 1038 scif_sas_remote_device_default_complete_io_handler, 1039 scif_sas_remote_device_default_continue_io_handler, 1040 scif_sas_remote_device_default_start_task_handler, 1041 scif_sas_remote_device_default_complete_task_handler 1042 }, 1043 scif_sas_remote_device_default_start_complete_handler, 1044 scif_sas_remote_device_default_stop_complete_handler, 1045 scif_sas_remote_device_default_ready_handler, 1046 scif_sas_remote_device_default_not_ready_handler, 1047 scif_sas_remote_device_default_start_io_handler, 1048 scif_sas_remote_device_default_complete_high_priority_io_handler 1049 }, 1050 // SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 1051 { 1052 { 1053 scif_sas_remote_device_default_start_handler, 1054 scif_sas_remote_device_default_stop_handler, 1055 scif_sas_remote_device_default_fail_handler, 1056 scif_sas_remote_device_default_destruct_handler, 1057 scif_sas_remote_device_default_reset_handler, 1058 scif_sas_remote_device_default_reset_complete_handler, 1059 scif_sas_remote_device_default_start_io_handler, 1060 scif_sas_remote_device_stopping_complete_io_handler, 1061 scif_sas_remote_device_default_continue_io_handler, 1062 scif_sas_remote_device_default_start_task_handler, 1063 scif_sas_remote_device_stopping_complete_task_handler 1064 }, 1065 scif_sas_remote_device_default_start_complete_handler, 1066 scif_sas_remote_device_stopping_stop_complete_handler, 1067 scif_sas_remote_device_default_ready_handler, 1068 scif_sas_remote_device_default_not_ready_handler, 1069 scif_sas_remote_device_default_start_io_handler, 1070 scif_sas_remote_device_stopping_complete_high_priority_io_handler 1071 }, 1072 // SCI_BASE_REMOTE_DEVICE_STATE_FAILED 1073 { 1074 { 1075 scif_sas_remote_device_default_start_handler, 1076 scif_sas_remote_device_failed_stop_handler, 1077 scif_sas_remote_device_default_fail_handler, 1078 scif_sas_remote_device_default_destruct_handler, 1079 scif_sas_remote_device_default_reset_handler, 1080 scif_sas_remote_device_default_reset_complete_handler, 1081 scif_sas_remote_device_default_start_io_handler, 1082 scif_sas_remote_device_default_complete_io_handler, 1083 scif_sas_remote_device_default_continue_io_handler, 1084 scif_sas_remote_device_default_start_task_handler, 1085 scif_sas_remote_device_default_complete_task_handler 1086 }, 1087 scif_sas_remote_device_default_start_complete_handler, 1088 scif_sas_remote_device_default_stop_complete_handler, 1089 scif_sas_remote_device_default_ready_handler, 1090 scif_sas_remote_device_default_not_ready_handler, 1091 scif_sas_remote_device_default_start_io_handler, 1092 scif_sas_remote_device_default_complete_high_priority_io_handler 1093 }, 1094 // SCI_BASE_REMOTE_DEVICE_STATE_RESETTING - is unused by framework 1095 { 1096 { 1097 scif_sas_remote_device_default_start_handler, 1098 scif_sas_remote_device_default_stop_handler, 1099 scif_sas_remote_device_default_fail_handler, 1100 scif_sas_remote_device_default_destruct_handler, 1101 scif_sas_remote_device_default_reset_handler, 1102 scif_sas_remote_device_default_reset_complete_handler, 1103 scif_sas_remote_device_default_start_io_handler, 1104 scif_sas_remote_device_default_complete_io_handler, 1105 scif_sas_remote_device_default_continue_io_handler, 1106 scif_sas_remote_device_default_start_task_handler, 1107 scif_sas_remote_device_default_complete_task_handler 1108 }, 1109 scif_sas_remote_device_default_start_complete_handler, 1110 scif_sas_remote_device_default_stop_complete_handler, 1111 scif_sas_remote_device_default_ready_handler, 1112 scif_sas_remote_device_default_not_ready_handler, 1113 scif_sas_remote_device_default_start_io_handler, 1114 scif_sas_remote_device_default_complete_high_priority_io_handler 1115 }, 1116#if !defined(DISABLE_WIDE_PORTED_TARGETS) 1117 // SCI_BASE_REMOTE_DEVICE_STATE_UPDATING_PORT_WIDTH 1118 { 1119 { 1120 scif_sas_remote_device_default_start_handler, 1121 scif_sas_remote_device_updating_port_width_state_stop_handler, 1122 scif_sas_remote_device_default_fail_handler, 1123 scif_sas_remote_device_default_destruct_handler, 1124 scif_sas_remote_device_default_reset_handler, 1125 scif_sas_remote_device_default_reset_complete_handler, 1126 scif_sas_remote_device_default_start_io_handler, 1127 scif_sas_remote_device_updating_port_width_state_complete_io_handler, 1128 scif_sas_remote_device_default_continue_io_handler, 1129 scif_sas_remote_device_default_start_task_handler, 1130 scif_sas_remote_device_default_complete_task_handler 1131 }, 1132 scif_sas_remote_device_updating_port_width_state_start_complete_handler, 1133 scif_sas_remote_device_updating_port_width_state_stop_complete_handler, 1134 scif_sas_remote_device_default_ready_handler, 1135 scif_sas_remote_device_default_not_ready_handler, 1136 scif_sas_remote_device_default_start_io_handler, 1137 scif_sas_remote_device_default_complete_high_priority_io_handler 1138 }, 1139#endif 1140 // SCI_BASE_REMOTE_DEVICE_STATE_FINAL 1141 { 1142 { 1143 scif_sas_remote_device_default_start_handler, 1144 scif_sas_remote_device_default_stop_handler, 1145 scif_sas_remote_device_default_fail_handler, 1146 scif_sas_remote_device_default_destruct_handler, 1147 scif_sas_remote_device_default_reset_handler, 1148 scif_sas_remote_device_default_reset_complete_handler, 1149 scif_sas_remote_device_default_start_io_handler, 1150 scif_sas_remote_device_default_complete_io_handler, 1151 scif_sas_remote_device_default_continue_io_handler, 1152 scif_sas_remote_device_default_start_task_handler, 1153 scif_sas_remote_device_default_complete_task_handler 1154 }, 1155 scif_sas_remote_device_default_start_complete_handler, 1156 scif_sas_remote_device_default_stop_complete_handler, 1157 scif_sas_remote_device_default_ready_handler, 1158 scif_sas_remote_device_default_not_ready_handler, 1159 scif_sas_remote_device_default_start_io_handler, 1160 scif_sas_remote_device_default_complete_high_priority_io_handler 1161 } 1162}; 1163 1164