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 domain states defined by the SCI_BASE_DOMAIN state 63 * machine. 64 * @note 65 * - The discover method must be synchronized with the 66 * controller's completion handler. The OS specific driver 67 * component is responsible for ensuring this occurs. If the 68 * discovery method is called from within the call 69 * tree of the completion routine, then no action is necessary. 70 */ 71 72 73 #include <dev/isci/scil/scic_port.h> 74 #include <dev/isci/scil/scic_io_request.h> 75 #include <dev/isci/scil/scif_sas_logger.h> 76 #include <dev/isci/scil/scif_sas_domain.h> 77 78 //****************************************************************************** 79 //* P R O T E C T E D M E T H O D S 80 //****************************************************************************** 81 82 //****************************************************************************** 83 //* S T A R T I N G H A N D L E R S 84 //****************************************************************************** 85 86 static 87 SCI_STATUS scif_sas_domain_starting_port_ready_handler( 88 SCI_BASE_DOMAIN_T * domain 89 ) 90 { 91 SCIF_LOG_TRACE(( 92 sci_base_object_get_logger(domain), 93 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 94 "scif_sas_domain_starting_port_ready_handler(0x%x) enter\n", 95 domain 96 )); 97 98 // The domain was previously completely stopped. Now that the port is 99 // ready we can transition the domain to the ready state. 100 sci_base_state_machine_change_state( 101 &domain->state_machine, SCI_BASE_DOMAIN_STATE_READY 102 ); 103 104 return SCI_SUCCESS; 105 } 106 107 //****************************************************************************** 108 //* R E A D Y H A N D L E R S 109 //****************************************************************************** 110 111 /** 112 * @brief This method provides READY state specific handling for 113 * when a user attempts to discover a domain. 114 * 115 * @param[in] domain This parameter specifies the domain object 116 * on which the user is attempting to perform a discover 117 * operation. 118 * 119 * @return This method returns an indication of whether the discover operation 120 * succeeded. 121 * @retval SCI_SUCCESSS This value is returned when the discover operation 122 * begins successfully. 123 */ 124 static 125 SCI_STATUS scif_sas_domain_ready_discover_handler( 126 SCI_BASE_DOMAIN_T * domain, 127 U32 op_timeout, 128 U32 device_timeout 129 ) 130 { 131 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)domain; 132 133 SCIF_LOG_TRACE(( 134 sci_base_object_get_logger(domain), 135 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 136 "scif_sas_domain_ready_discover_handler(0x%x, 0x%x, 0x%x) enter\n", 137 domain, op_timeout, device_timeout 138 )); 139 140 fw_domain->operation.timeout = op_timeout; 141 fw_domain->operation.device_timeout = device_timeout; 142 fw_domain->operation.status = SCI_SUCCESS; 143 144 scif_cb_timer_start( 145 fw_domain->controller, 146 fw_domain->operation.timer, 147 fw_domain->operation.timeout 148 ); 149 150 scif_sas_domain_transition_to_discovering_state(fw_domain); 151 152 return fw_domain->operation.status; 153 } 154 155 /** 156 * @brief This method provides READY state processing for reception of a 157 * port NOT ready notification from the core. 158 * 159 * @param[in] domain This parameter specifies the domain object 160 * on which the core port has just come ready. 161 * 162 * @return 163 */ 164 static 165 SCI_STATUS scif_sas_domain_ready_port_not_ready_handler( 166 SCI_BASE_DOMAIN_T * domain, 167 U32 reason_code 168 ) 169 { 170 SCIF_LOG_TRACE(( 171 sci_base_object_get_logger(domain), 172 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 173 "scif_sas_domain_ready_port_not_ready_handler(0x%x, 0x%x) enter\n", 174 domain, 175 reason_code 176 )); 177 178 if (reason_code != SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED) 179 { 180 // Change to the STOPPING state to cause existing request 181 // completions to be terminated and devices removed. 182 sci_base_state_machine_change_state( 183 &domain->state_machine, SCI_BASE_DOMAIN_STATE_STOPPING 184 ); 185 } 186 187 return SCI_SUCCESS; 188 } 189 190 /** 191 * @brief This method provides READY state specific handling for 192 * when a user attempts to start an IO request. 193 * 194 * @param[in] domain This parameter specifies the domain object 195 * on which the user is attempting to perform a start IO 196 * operation. 197 * @param[in] remote_device This parameter specifies the remote device 198 * object on which the user is attempting to perform a start IO 199 * operation. 200 * @param[in] io_request This parameter specifies the io request that is 201 * being started. 202 * 203 * @return This method returns an indication of whether the start IO 204 * operation succeeded. 205 * @retval SCI_SUCCESS This value is returned when the start IO operation 206 * begins successfully. 207 */ 208 static 209 SCI_STATUS scif_sas_domain_ready_start_io_handler( 210 SCI_BASE_DOMAIN_T * domain, 211 SCI_BASE_REMOTE_DEVICE_T * remote_device, 212 SCI_BASE_REQUEST_T * io_request 213 ) 214 { 215 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain; 216 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 217 remote_device; 218 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) io_request; 219 SCI_STATUS status; 220 221 SCIF_LOG_TRACE(( 222 sci_base_object_get_logger(domain), 223 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST, 224 "scif_sas_domain_ready_start_io_handler(0x%x, 0x%x, 0x%x) enter\n", 225 domain, remote_device, io_request 226 )); 227 228 status = fw_device->state_handlers->parent.start_io_handler( 229 &fw_device->parent, &fw_request->parent 230 ); 231 232 if (status == SCI_SUCCESS) 233 { 234 // Add the IO to the list of outstanding requests on the domain. 235 sci_fast_list_insert_tail( 236 &fw_domain->request_list, &fw_request->list_element 237 ); 238 } 239 240 return status; 241 } 242 243 /** 244 * @brief This method provides READY state specific handling for 245 * when a user attempts to complete an IO request. 246 * 247 * @param[in] domain This parameter specifies the domain object 248 * on which the user is attempting to perform a complete IO 249 * operation. 250 * @param[in] remote_device This parameter specifies the remote device 251 * object on which the user is attempting to perform a complete 252 * IO operation. 253 * @param[in] io_request This parameter specifies the io request that is 254 * being completed. 255 * 256 * @return This method returns an indication of whether the complete IO 257 * operation succeeded. 258 * @retval SCI_SUCCESS This value is returned when the complete IO operation 259 * is successful. 260 */ 261 static 262 SCI_STATUS scif_sas_domain_ready_complete_io_handler( 263 SCI_BASE_DOMAIN_T * domain, 264 SCI_BASE_REMOTE_DEVICE_T * remote_device, 265 SCI_BASE_REQUEST_T * io_request 266 ) 267 { 268 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 269 remote_device; 270 SCIF_SAS_REQUEST_T * fw_request= (SCIF_SAS_REQUEST_T*) io_request; 271 272 SCIF_LOG_TRACE(( 273 sci_base_object_get_logger(domain), 274 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST, 275 "scif_sas_domain_ready_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n", 276 domain, remote_device, io_request 277 )); 278 279 // Remove the IO from the list of outstanding requests on the domain. 280 sci_fast_list_remove_element(&fw_request->list_element); 281 282 return fw_device->state_handlers->parent.complete_io_handler( 283 &fw_device->parent, &fw_request->parent 284 ); 285 } 286 287 /** 288 * @brief This method provides READY state specific handling for 289 * when a user attempts to continue an IO request. 290 * 291 * @param[in] domain This parameter specifies the domain object 292 * on which the user is attempting to perform a continue IO 293 * operation. 294 * @param[in] remote_device This parameter specifies the remote device 295 * object on which the user is attempting to perform a start IO 296 * operation. 297 * @param[in] io_request This parameter specifies the io request that is 298 * being started. 299 * 300 * @return This method returns an indication of whether the continue IO 301 * operation succeeded. 302 * @retval SCI_SUCCESS This value is returned when the continue IO operation 303 * begins successfully. 304 */ 305 static 306 SCI_STATUS scif_sas_domain_ready_continue_io_handler( 307 SCI_BASE_DOMAIN_T * domain, 308 SCI_BASE_REMOTE_DEVICE_T * remote_device, 309 SCI_BASE_REQUEST_T * io_request 310 ) 311 { 312 SCIF_LOG_TRACE(( 313 sci_base_object_get_logger(domain), 314 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST, 315 "scif_sas_domain_ready_continue_io_handler(0x%x, 0x%x, 0x%x) enter\n", 316 domain, remote_device, io_request 317 )); 318 319 /// @todo fix return code handling. 320 return SCI_FAILURE; 321 } 322 323 /** 324 * @brief This method provides READY state specific handling for 325 * when a user attempts to start a task request. 326 * 327 * @param[in] domain This parameter specifies the domain object 328 * on which the user is attempting to perform a start task 329 * operation. 330 * @param[in] remote_device This parameter specifies the remote device 331 * object on which the user is attempting to perform a start IO 332 * operation. 333 * @param[in] task_request This parameter specifies the task request that 334 * is being started. 335 * 336 * @return This method returns an indication of whether the start task 337 * operation succeeded. 338 * @retval SCI_SUCCESS This value is returned when the start task operation 339 * begins successfully. 340 */ 341 static 342 SCI_STATUS scif_sas_domain_ready_start_task_handler( 343 SCI_BASE_DOMAIN_T * domain, 344 SCI_BASE_REMOTE_DEVICE_T * remote_device, 345 SCI_BASE_REQUEST_T * task_request 346 ) 347 { 348 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain; 349 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 350 remote_device; 351 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) task_request; 352 SCI_STATUS status; 353 354 SCIF_LOG_TRACE(( 355 sci_base_object_get_logger(domain), 356 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 357 "scif_sas_domain_ready_start_task_handler(0x%x, 0x%x, 0x%x) enter\n", 358 domain, remote_device, task_request 359 )); 360 361 status = fw_device->state_handlers->parent.start_task_handler( 362 &fw_device->parent, &fw_request->parent 363 ); 364 365 if (status == SCI_SUCCESS) 366 { 367 // Add the task to the list of outstanding requests on the domain. 368 sci_fast_list_insert_tail( 369 &fw_domain->request_list, &fw_request->list_element 370 ); 371 } 372 373 return status; 374 } 375 376 /** 377 * @brief This method provides READY state specific handling for 378 * when a user attempts to complete a task request. 379 * 380 * @param[in] domain This parameter specifies the domain object 381 * on which the user is attempting to perform a complete task 382 * operation. 383 * @param[in] remote_device This parameter specifies the remote device 384 * object on which the user is attempting to perform a start IO 385 * operation. 386 * @param[in] task_request This parameter specifies the task request that 387 * is being started. 388 * 389 * @return This method returns an indication of whether the complete task 390 * operation succeeded. 391 * @retval SCI_SUCCESS This value is returned when the complete task operation 392 * begins successfully. 393 */ 394 static 395 SCI_STATUS scif_sas_domain_ready_complete_task_handler( 396 SCI_BASE_DOMAIN_T * domain, 397 SCI_BASE_REMOTE_DEVICE_T * remote_device, 398 SCI_BASE_REQUEST_T * task_request 399 ) 400 { 401 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 402 remote_device; 403 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) task_request; 404 405 SCIF_LOG_TRACE(( 406 sci_base_object_get_logger(domain), 407 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 408 "scif_sas_domain_ready_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n", 409 domain, remote_device, task_request 410 )); 411 412 // Remove the IO from the list of outstanding requests on the domain. 413 sci_fast_list_remove_element(&fw_request->list_element); 414 415 return fw_device->state_handlers->parent.complete_task_handler( 416 &fw_device->parent, &fw_request->parent 417 ); 418 } 419 420 421 /** 422 * @brief This method provides READY state specific handling for when a user 423 * attempts to start a high priority IO request. 424 * 425 * @param[in] domain This parameter specifies the domain object 426 * on which the user is attempting to perform a start high priority 427 * IO operation (which is exclusively for Phy Control hard reset). 428 * @param[in] remote_device This parameter specifies the remote device 429 * object on which the user is attempting to perform a start 430 * high priority IO operation. 431 * @param[in] io_request This parameter specifies the io request that is 432 * being started. 433 * 434 * @return This method returns an indication of whether the start IO 435 * operation succeeded. 436 * @retval SCI_SUCCESS This value is returned when the start IO operation 437 * begins successfully. 438 */ 439 static 440 SCI_STATUS scif_sas_domain_ready_start_high_priority_io_handler( 441 SCI_BASE_DOMAIN_T * domain, 442 SCI_BASE_REMOTE_DEVICE_T * remote_device, 443 SCI_BASE_REQUEST_T * io_request 444 ) 445 { 446 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain; 447 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 448 remote_device; 449 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) io_request; 450 SCI_STATUS status; 451 452 SCIF_LOG_TRACE(( 453 sci_base_object_get_logger(domain), 454 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST, 455 "scif_sas_domain_ready_start_high_priority_request_handler(0x%x, 0x%x, 0x%x) enter\n", 456 domain, remote_device, io_request 457 )); 458 459 status = fw_device->state_handlers->start_high_priority_io_handler( 460 &fw_device->parent, &fw_request->parent 461 ); 462 463 if (status == SCI_SUCCESS) 464 { 465 // Add the IO to the list of outstanding requests on the domain. 466 467 // When domain is in READY state, this high priority io is likely 468 // a smp Phy Control or Discover request sent to parent device of 469 // a target device, which is to be Target Reset. This high priority 470 // IO's probably has already been added to the domain's list as a 471 // SCIF_SAS_TASK_REQUEST. We need to check if it is already on the 472 // list. 473 474 if ( ! sci_fast_list_is_on_this_list( 475 &fw_domain->request_list, &fw_request->list_element)) 476 477 sci_fast_list_insert_tail( 478 &fw_domain->request_list, &fw_request->list_element 479 ); 480 } 481 482 return status; 483 } 484 485 486 /** 487 * @brief This method provides READY state specific handling for 488 * when a user attempts to complete an high priroity IO request. 489 * 490 * @param[in] domain This parameter specifies the domain object 491 * on which the user is attempting to perform a complete high 492 * priority IO operation (which is exclusively for Phy Control 493 * hard reset). 494 * @param[in] remote_device This parameter specifies the remote device 495 * object on which the user is attempting to perform a complete 496 * IO operation. 497 * @param[in] io_request This parameter specifies the io request that is 498 * being completed. 499 * 500 * @return This method returns an indication of whether the complete IO 501 * operation succeeded. 502 * @retval SCI_SUCCESS This value is returned when the complete IO operation 503 * is successful. 504 */ 505 static 506 SCI_STATUS scif_sas_domain_ready_complete_high_priority_io_handler( 507 SCI_BASE_DOMAIN_T * domain, 508 SCI_BASE_REMOTE_DEVICE_T * remote_device, 509 SCI_BASE_REQUEST_T * io_request, 510 void * response_data, 511 SCI_IO_STATUS completion_status 512 ) 513 { 514 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 515 remote_device; 516 SCIF_SAS_REQUEST_T * fw_request= (SCIF_SAS_REQUEST_T*) io_request; 517 518 SCIC_TRANSPORT_PROTOCOL protocol; 519 520 SCIF_LOG_TRACE(( 521 sci_base_object_get_logger(domain), 522 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST, 523 "scif_sas_domain_ready_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 524 domain, remote_device, io_request, response_data 525 )); 526 527 protocol = scic_io_request_get_protocol(fw_request->core_object); 528 529 // If the request is an SMP HARD/LINK RESET request, then the request 530 // came through the task management path (partially). As a result, 531 // the accounting for the request is managed in the task request 532 // completion path. Thus, only change the domain request counter if 533 // the request is not an SMP target reset of some sort. 534 if ( 535 (protocol != SCIC_SMP_PROTOCOL) 536 || (fw_device->protocol_device.smp_device.current_activity != 537 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_TARGET_RESET) 538 ) 539 { 540 sci_fast_list_remove_element(&fw_request->list_element); 541 } 542 543 return fw_device->state_handlers->complete_high_priority_io_handler( 544 &fw_device->parent, &fw_request->parent, response_data, completion_status 545 ); 546 } 547 548 //****************************************************************************** 549 //* S T O P P I N G H A N D L E R S 550 //****************************************************************************** 551 552 static 553 SCI_STATUS scif_sas_domain_stopping_device_stop_complete_handler( 554 SCI_BASE_DOMAIN_T * domain, 555 SCI_BASE_REMOTE_DEVICE_T * remote_device 556 ) 557 { 558 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain; 559 560 SCIF_LOG_TRACE(( 561 sci_base_object_get_logger(domain), 562 SCIF_LOG_OBJECT_DOMAIN, 563 "scif_sas_domain_stopping_device_stop_complete_handler(0x%x, 0x%x) enter\n", 564 domain, remote_device 565 )); 566 567 // Attempt to transition to the stopped state. 568 scif_sas_domain_transition_to_stopped_state(fw_domain); 569 570 return SCI_SUCCESS; 571 } 572 573 /** 574 * @brief This method provides STOPPING state specific handling for 575 * when a user attempts to complete an IO request. 576 * 577 * @param[in] domain This parameter specifies the domain object 578 * on which the user is attempting to perform a complete IO 579 * operation. 580 * @param[in] remote_device This parameter specifies the remote device 581 * object on which the user is attempting to perform a complete 582 * IO operation. 583 * @param[in] io_request This parameter specifies the io request that is 584 * being completed. 585 * 586 * @return This method returns an indication of whether the complete IO 587 * operation succeeded. 588 * @retval SCI_SUCCESS This value is returned when the complete IO operation 589 * is successful. 590 */ 591 static 592 SCI_STATUS scif_sas_domain_stopping_complete_io_handler( 593 SCI_BASE_DOMAIN_T * domain, 594 SCI_BASE_REMOTE_DEVICE_T * remote_device, 595 SCI_BASE_REQUEST_T * io_request 596 ) 597 { 598 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain; 599 SCI_STATUS status; 600 601 SCIF_LOG_TRACE(( 602 sci_base_object_get_logger(domain), 603 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST, 604 "scif_sas_domain_stopping_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n", 605 domain, remote_device, io_request 606 )); 607 608 status = scif_sas_domain_ready_complete_io_handler( 609 domain, remote_device, io_request 610 ); 611 612 // Attempt to transition to the stopped state. 613 scif_sas_domain_transition_to_stopped_state(fw_domain); 614 615 return status; 616 } 617 618 619 /** 620 * @brief This method provides STOPPING state specific handling for 621 * when a user attempts to complete an IO request. 622 * 623 * @param[in] domain This parameter specifies the domain object 624 * on which the user is attempting to perform a complete IO 625 * operation. 626 * @param[in] remote_device This parameter specifies the remote device 627 * object on which the user is attempting to perform a complete 628 * IO operation. 629 * @param[in] io_request This parameter specifies the io request that is 630 * being completed. 631 * 632 * @return This method returns an indication of whether the complete IO 633 * operation succeeded. 634 * @retval SCI_SUCCESS This value is returned when the complete IO operation 635 * is successful. 636 */ 637 static 638 SCI_STATUS scif_sas_domain_stopping_complete_high_priority_io_handler( 639 SCI_BASE_DOMAIN_T * domain, 640 SCI_BASE_REMOTE_DEVICE_T * remote_device, 641 SCI_BASE_REQUEST_T * io_request, 642 void * response_data, 643 SCI_IO_STATUS completion_status 644 ) 645 { 646 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain; 647 SCI_STATUS status; 648 649 SCIF_LOG_TRACE(( 650 sci_base_object_get_logger(domain), 651 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST, 652 "scif_sas_domain_stopping_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n", 653 domain, remote_device, io_request 654 )); 655 656 status = scif_sas_domain_ready_complete_high_priority_io_handler( 657 domain, remote_device, io_request, response_data, completion_status 658 ); 659 660 // Attempt to transition to the stopped state. 661 scif_sas_domain_transition_to_stopped_state(fw_domain); 662 663 return status; 664 } 665 666 667 /** 668 * @brief This method provides STOPPING state specific handling for 669 * when a user attempts to complete a task request. 670 * 671 * @param[in] domain This parameter specifies the domain object 672 * on which the user is attempting to perform a complete task 673 * operation. 674 * 675 * @return This method returns an indication of whether the complete task 676 * operation succeeded. 677 * @retval SCI_SUCCESS This value is returned when the complete task operation 678 * begins successfully. 679 */ 680 static 681 SCI_STATUS scif_sas_domain_stopping_complete_task_handler( 682 SCI_BASE_DOMAIN_T * domain, 683 SCI_BASE_REMOTE_DEVICE_T * remote_device, 684 SCI_BASE_REQUEST_T * task_request 685 ) 686 { 687 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain; 688 SCI_STATUS status; 689 690 SCIF_LOG_TRACE(( 691 sci_base_object_get_logger(domain), 692 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 693 "scif_sas_domain_stopping_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n", 694 domain, remote_device, task_request 695 )); 696 697 status = scif_sas_domain_ready_complete_task_handler( 698 domain, remote_device, task_request 699 ); 700 701 // Attempt to transition to the stopped state. 702 scif_sas_domain_transition_to_stopped_state(fw_domain); 703 704 return SCI_SUCCESS; 705 } 706 707 //****************************************************************************** 708 //* D I S C O V E R I N G H A N D L E R S 709 //****************************************************************************** 710 711 /** 712 * @brief This method provides DISCOVERING state specific processing for 713 * reception of a port NOT ready notification from the core. A port 714 * NOT ready notification forces the discovery operation to complete 715 * in error. Additionally, all IOs are aborted and devices removed. 716 * 717 * @param[in] domain This parameter specifies the domain object 718 * for which the core port is no longer ready. 719 * 720 * @return 721 */ 722 static 723 SCI_STATUS scif_sas_domain_discovering_port_not_ready_handler( 724 SCI_BASE_DOMAIN_T * domain, 725 U32 reason_code 726 ) 727 { 728 SCIF_LOG_TRACE(( 729 sci_base_object_get_logger(domain), 730 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 731 "scif_sas_domain_discovering_port_not_ready_handler(0x%x, 0x%x) enter\n", 732 domain, 733 reason_code 734 )); 735 736 // Change to the STOPPING state to cause existing request 737 // completions to be terminated and devices removed. 738 sci_base_state_machine_change_state( 739 &domain->state_machine, SCI_BASE_DOMAIN_STATE_STOPPING 740 ); 741 742 return SCI_SUCCESS; 743 } 744 745 static 746 SCI_STATUS scif_sas_domain_discovering_device_start_complete_handler( 747 SCI_BASE_DOMAIN_T * domain, 748 SCI_BASE_REMOTE_DEVICE_T * remote_device 749 ) 750 { 751 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)domain; 752 753 SCIF_LOG_TRACE(( 754 sci_base_object_get_logger(domain), 755 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 756 "scif_sas_domain_discovering_device_start_complete_handler(0x%x) enter\n", 757 domain, remote_device 758 )); 759 760 //domain will decide what's next step. 761 scif_sas_domain_continue_discover(fw_domain); 762 763 return SCI_SUCCESS; 764 } 765 766 // --------------------------------------------------------------------------- 767 768 static 769 SCI_STATUS scif_sas_domain_discovering_device_stop_complete_handler( 770 SCI_BASE_DOMAIN_T * domain, 771 SCI_BASE_REMOTE_DEVICE_T * remote_device 772 ) 773 { 774 SCIF_LOG_TRACE(( 775 sci_base_object_get_logger(domain), 776 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 777 "scif_sas_domain_discovering_device_stop_complete_handler(0x%x) enter\n", 778 domain, remote_device 779 )); 780 781 return SCI_FAILURE; 782 } 783 784 785 /** 786 * @brief This method provides DISCOVERING state specific handling for when a user 787 * attempts to start a high priority IO request. 788 * 789 * @param[in] domain This parameter specifies the domain object 790 * on which the user is attempting to perform a start IO 791 * operation. 792 * @param[in] remote_device This parameter specifies the remote device 793 * object on which the user is attempting to perform a start IO 794 * operation. 795 * @param[in] io_request This parameter specifies the io request that is 796 * being started. 797 * 798 * @return This method returns an indication of whether the start IO 799 * operation succeeded. 800 * @retval SCI_SUCCESS This value is returned when the start IO operation 801 * begins successfully. 802 */ 803 static 804 SCI_STATUS scif_sas_domain_discovering_start_high_priority_io_handler( 805 SCI_BASE_DOMAIN_T * domain, 806 SCI_BASE_REMOTE_DEVICE_T * remote_device, 807 SCI_BASE_REQUEST_T * io_request 808 ) 809 { 810 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain; 811 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 812 remote_device; 813 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) io_request; 814 SCI_STATUS status; 815 816 SCIF_LOG_TRACE(( 817 sci_base_object_get_logger(domain), 818 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST, 819 "scif_sas_domain_discovery_start_high_priority_request_handler(0x%x, 0x%x, 0x%x) enter\n", 820 domain, remote_device, io_request 821 )); 822 823 status = fw_device->state_handlers->start_high_priority_io_handler( 824 &fw_device->parent, &fw_request->parent 825 ); 826 827 if (status == SCI_SUCCESS) 828 { 829 // Add the IO to the list of outstanding requests on the domain. 830 831 // It is possible this high priority IO's has already been added to 832 // the domain's list as a SCIF_SAS_TASK_REQUEST. We need to check 833 // if it is already on the list. 834 if ( ! sci_fast_list_is_on_this_list( 835 &fw_domain->request_list, &fw_request->list_element)) 836 837 sci_fast_list_insert_tail( 838 &fw_domain->request_list, &fw_request->list_element 839 ); 840 } 841 842 return status; 843 } 844 845 846 /** 847 * @brief This method provides DISCOVERING state specific handling for 848 * when a user attempts to complete an IO request. User IOs are 849 * allowed to be completed during discovery. 850 * 851 * @param[in] domain This parameter specifies the domain object 852 * on which the user is attempting to perform a complete IO 853 * operation. 854 * @param[in] remote_device This parameter specifies the remote device 855 * object on which the user is attempting to perform a complete 856 * IO operation. 857 * @param[in] io_request This parameter specifies the io request that is 858 * being completed. 859 * 860 * @return This method returns an indication of whether the complete IO 861 * operation succeeded. 862 * @retval SCI_SUCCESS This value is returned when the complete IO operation 863 * is successful. 864 */ 865 static 866 SCI_STATUS scif_sas_domain_discovering_complete_io_handler( 867 SCI_BASE_DOMAIN_T * domain, 868 SCI_BASE_REMOTE_DEVICE_T * remote_device, 869 SCI_BASE_REQUEST_T * io_request 870 ) 871 { 872 SCIF_LOG_TRACE(( 873 sci_base_object_get_logger(domain), 874 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST, 875 "scif_sas_domain_discovering_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n", 876 domain, remote_device, io_request 877 )); 878 879 return scif_sas_domain_ready_complete_io_handler( 880 domain, remote_device, io_request 881 ); 882 } 883 884 /** 885 * @brief This method provides DISCOVERING state specific handling for 886 * when a user attempts to complete an high priroity IO request. User 887 * IOs are allowed to be completed during discovery. 888 * 889 * @param[in] domain This parameter specifies the domain object 890 * on which the user is attempting to perform a complete IO 891 * operation. 892 * @param[in] remote_device This parameter specifies the remote device 893 * object on which the user is attempting to perform a complete 894 * IO operation. 895 * @param[in] io_request This parameter specifies the io request that is 896 * being completed. 897 * 898 * @return This method returns an indication of whether the complete IO 899 * operation succeeded. 900 * @retval SCI_SUCCESS This value is returned when the complete IO operation 901 * is successful. 902 */ 903 static 904 SCI_STATUS scif_sas_domain_discovering_complete_high_priority_io_handler( 905 SCI_BASE_DOMAIN_T * domain, 906 SCI_BASE_REMOTE_DEVICE_T * remote_device, 907 SCI_BASE_REQUEST_T * io_request, 908 void * response_data, 909 SCI_IO_STATUS completion_status 910 ) 911 { 912 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 913 remote_device; 914 SCIF_SAS_REQUEST_T * fw_request= (SCIF_SAS_REQUEST_T*) io_request; 915 916 SCIC_TRANSPORT_PROTOCOL protocol; 917 918 SCIF_LOG_TRACE(( 919 sci_base_object_get_logger(domain), 920 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST, 921 "scif_sas_domain_discovering_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 922 domain, remote_device, io_request, response_data 923 )); 924 925 protocol = scic_io_request_get_protocol(fw_request->core_object); 926 927 // Remove the IO from the list of outstanding requests on the domain. 928 929 // If the request is an SMP HARD/LINK RESET request, then the request 930 // came through the task management path (partially). As a result, 931 // the accounting for the request is managed in the task request 932 // completion path. Thus, only change the domain request counter if 933 // the request is not an SMP target reset of some sort. 934 if ( 935 (protocol != SCIC_SMP_PROTOCOL) 936 || (fw_device->protocol_device.smp_device.current_activity != 937 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_TARGET_RESET) 938 ) 939 { 940 sci_fast_list_remove_element(&fw_request->list_element); 941 } 942 943 return fw_device->state_handlers->complete_high_priority_io_handler( 944 &fw_device->parent, &fw_request->parent, response_data, completion_status 945 ); 946 } 947 948 949 /** 950 * @brief This method provides DISCOVERING state specific handling for 951 * when the framework attempts to complete an IO request. Internal 952 * Framework IOs allowed to be continued during discovery. 953 * 954 * @param[in] domain This parameter specifies the domain object 955 * on which the user is attempting to perform a continue IO 956 * operation. 957 * @param[in] remote_device This parameter specifies the remote device 958 * object on which the user is attempting to perform a continue 959 * IO operation. 960 * @param[in] io_request This parameter specifies the io request that is 961 * being continued. 962 * 963 * @return This method returns an indication of whether the continue IO 964 * operation succeeded. 965 * @retval SCI_SUCCESS This value is returned when the continue IO operation 966 * is successful. 967 */ 968 static 969 SCI_STATUS scif_sas_domain_discovering_continue_io_handler( 970 SCI_BASE_DOMAIN_T * domain, 971 SCI_BASE_REMOTE_DEVICE_T * remote_device, 972 SCI_BASE_REQUEST_T * io_request 973 ) 974 { 975 SCIF_LOG_TRACE(( 976 sci_base_object_get_logger(domain), 977 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST, 978 "scif_sas_domain_discovering_continue_io_handler(0x%x, 0x%x, 0x%x) enter\n", 979 domain, remote_device, io_request 980 )); 981 982 /// @todo fix return code handling. 983 return SCI_FAILURE; 984 } 985 986 987 /** 988 * @brief This method provides handling when a user attempts to start 989 * a task on a domain in DISCOVER state, only hard reset is allowed. 990 * 991 * @param[in] domain This parameter specifies the domain object 992 * on which the user is attempting to perform a start task 993 * operation. 994 * @param[in] remote_device This parameter specifies the remote device 995 * object on which the user is attempting to perform a start IO 996 * operation. 997 * @param[in] task_request This parameter specifies the task request that 998 * is being started. 999 * 1000 * @return This method returns a status of start task operations 1001 * @retval SCI_FAILURE_INVALID_STATE This value is returned for any tasks, 1002 * except for HARD RESET. 1003 */ 1004 static 1005 SCI_STATUS scif_sas_domain_discovering_start_task_handler( 1006 SCI_BASE_DOMAIN_T * domain, 1007 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1008 SCI_BASE_REQUEST_T * task_request 1009 ) 1010 { 1011 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 1012 remote_device; 1013 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*)task_request; 1014 1015 //Only let target reset go through. 1016 if (scif_sas_task_request_get_function(fw_task) 1017 == SCI_SAS_HARD_RESET) 1018 { 1019 //If the domain is in the middle of smp DISCOVER process, 1020 //interrupt it. After target reset is done, resume the smp DISCOVERY. 1021 scif_sas_domain_cancel_smp_activities(fw_device->domain); 1022 1023 return scif_sas_domain_ready_start_task_handler(domain, remote_device, task_request); 1024 } 1025 else{ 1026 SCIF_LOG_WARNING(( 1027 sci_base_object_get_logger(domain), 1028 SCIF_LOG_OBJECT_DOMAIN, 1029 "Domain:0x%x Device:0x%x State:0x%x start task message invalid\n", 1030 domain, remote_device, 1031 sci_base_state_machine_get_state(&domain->state_machine) 1032 )); 1033 1034 return SCI_FAILURE_INVALID_STATE; 1035 } 1036 } 1037 1038 1039 /** 1040 * @brief This method provides DISCOVERING state specific handling for 1041 * when a user attempts to complete a task request. User task 1042 * management requests are allowed to be completed during discovery. 1043 * 1044 * @param[in] domain This parameter specifies the domain object 1045 * on which the user is attempting to perform a complete IO 1046 * operation. 1047 * @param[in] remote_device This parameter specifies the remote device 1048 * object on which the user is attempting to perform a complete 1049 * IO operation. 1050 * @param[in] task_request This parameter specifies the task request that 1051 * is being completed. 1052 * 1053 * @return This method returns an indication of whether the complete task 1054 * management operation succeeded. 1055 * @retval SCI_SUCCESS This value is returned when the complete task request 1056 * is successful. 1057 */ 1058 static 1059 SCI_STATUS scif_sas_domain_discovering_complete_task_handler( 1060 SCI_BASE_DOMAIN_T * domain, 1061 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1062 SCI_BASE_REQUEST_T * task_request 1063 ) 1064 { 1065 SCI_STATUS status; 1066 1067 SCIF_LOG_TRACE(( 1068 sci_base_object_get_logger(domain), 1069 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 1070 "scif_sas_domain_discovering_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n", 1071 domain, remote_device, task_request 1072 )); 1073 1074 status = scif_sas_domain_ready_complete_task_handler( 1075 domain, remote_device, task_request 1076 ); 1077 1078 return status; 1079 } 1080 1081 //****************************************************************************** 1082 //* D E F A U L T H A N D L E R S 1083 //****************************************************************************** 1084 1085 /** 1086 * @brief This method provides default handling (i.e. returns an error) 1087 * when a user attempts to discover a domain and a discovery 1088 * operation is not allowed. 1089 * 1090 * @param[in] domain This parameter specifies the domain object 1091 * on which the user is attempting to perform an discover 1092 * operation. 1093 * @param[in] op_timeout This parameter specifies the timeout 1094 * (in milliseconds) for the entire discovery operation. 1095 * This timeout value should be some multiple of the 1096 * individual device_timeout value. 1097 * @param[in] device_timeout This parameter specifies the timeout 1098 * (in milliseconds) for an individual device being discovered 1099 * and configured during this operation. 1100 * 1101 * @return This method returns an indication that discovery operations 1102 * are not allowed. 1103 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1104 */ 1105 static 1106 SCI_STATUS scif_sas_domain_default_discover_handler( 1107 SCI_BASE_DOMAIN_T * domain, 1108 U32 op_timeout, 1109 U32 device_timeout 1110 ) 1111 { 1112 SCIF_LOG_WARNING(( 1113 sci_base_object_get_logger((SCIF_SAS_DOMAIN_T *)domain), 1114 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 1115 "Domain:0x%x State:0x%x requested to discover in invalid state\n", 1116 domain, 1117 sci_base_state_machine_get_state(&domain->state_machine) 1118 )); 1119 1120 return SCI_FAILURE_INVALID_STATE; 1121 } 1122 1123 /** 1124 * @brief This method provides default processing for reception of a port 1125 * ready notification from the core. 1126 * 1127 * @param[in] domain This parameter specifies the domain object 1128 * on which the core port has just come ready. 1129 * 1130 * @return 1131 */ 1132 static 1133 SCI_STATUS scif_sas_domain_default_port_ready_handler( 1134 SCI_BASE_DOMAIN_T * domain 1135 ) 1136 { 1137 SCIF_LOG_INFO(( 1138 sci_base_object_get_logger(domain), 1139 SCIF_LOG_OBJECT_DOMAIN, 1140 "Domain:0x%x State:0x%x port now ready\n", 1141 domain, 1142 sci_base_state_machine_get_state(&domain->state_machine) 1143 )); 1144 1145 return SCI_SUCCESS; 1146 } 1147 1148 /** 1149 * @brief This method provides default processing for reception of a port 1150 * NOT ready notification from the core. 1151 * 1152 * @param[in] domain This parameter specifies the domain object 1153 * on which the core port has just come ready. 1154 * 1155 * @return 1156 */ 1157 static 1158 SCI_STATUS scif_sas_domain_default_port_not_ready_handler( 1159 SCI_BASE_DOMAIN_T * domain, 1160 U32 reason_code 1161 ) 1162 { 1163 SCIF_LOG_WARNING(( 1164 sci_base_object_get_logger(domain), 1165 SCIF_LOG_OBJECT_DOMAIN, 1166 "Domain:0x%x State:0x%x Port Not Ready 0x%x in invalid state\n", 1167 domain, 1168 sci_base_state_machine_get_state(&domain->state_machine), 1169 reason_code 1170 )); 1171 1172 return SCI_FAILURE_INVALID_STATE; 1173 } 1174 1175 /** 1176 * @brief This method provides default handling (i.e. returns an error) 1177 * when a user attempts to start an IO on a domain and a start 1178 * IO operation is not allowed. 1179 * 1180 * @param[in] domain This parameter specifies the domain object 1181 * on which the user is attempting to perform a start IO 1182 * operation. 1183 * @param[in] remote_device This parameter specifies the remote device 1184 * object on which the user is attempting to perform a start IO 1185 * operation. 1186 * @param[in] io_request This parameter specifies the io request that is 1187 * being started. 1188 * 1189 * @return This method returns an indication that start IO operations 1190 * are not allowed. 1191 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1192 */ 1193 static 1194 SCI_STATUS scif_sas_domain_default_start_io_handler( 1195 SCI_BASE_DOMAIN_T * domain, 1196 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1197 SCI_BASE_REQUEST_T * io_request 1198 ) 1199 { 1200 SCIF_LOG_WARNING(( 1201 sci_base_object_get_logger(domain), 1202 SCIF_LOG_OBJECT_DOMAIN, 1203 "Domain:0x%x Device:0x%x State:0x%x start IO message invalid\n", 1204 domain, remote_device, 1205 sci_base_state_machine_get_state(&domain->state_machine) 1206 )); 1207 1208 return SCI_FAILURE_INVALID_STATE; 1209 } 1210 1211 /** 1212 * @brief This method provides default handling (i.e. returns an error) 1213 * when a user attempts to complete an IO on a domain and a 1214 * complete IO operation is not allowed. 1215 * 1216 * @param[in] domain This parameter specifies the domain object 1217 * on which the user is attempting to perform a complete IO 1218 * operation. 1219 * @param[in] remote_device This parameter specifies the remote device 1220 * object on which the user is attempting to perform a complete IO 1221 * operation. 1222 * @param[in] io_request This parameter specifies the io request that is 1223 * being completed. 1224 * 1225 * @return This method returns an indication that complete IO operations 1226 * are not allowed. 1227 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1228 */ 1229 static 1230 SCI_STATUS scif_sas_domain_default_complete_io_handler( 1231 SCI_BASE_DOMAIN_T * domain, 1232 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1233 SCI_BASE_REQUEST_T * io_request 1234 ) 1235 { 1236 SCIF_LOG_WARNING(( 1237 sci_base_object_get_logger(domain), 1238 SCIF_LOG_OBJECT_DOMAIN, 1239 "Domain:0x%x Device:0x%x State:0x%x complete IO message invalid\n", 1240 domain, remote_device, 1241 sci_base_state_machine_get_state(&domain->state_machine) 1242 )); 1243 1244 return SCI_FAILURE_INVALID_STATE; 1245 } 1246 1247 1248 /** 1249 * @brief This method provides default handling (i.e. returns an error) 1250 * when a user attempts to complete an IO on a domain and a 1251 * complete IO operation is not allowed. 1252 * 1253 * @param[in] domain This parameter specifies the domain object 1254 * on which the user is attempting to perform a complete IO 1255 * operation. 1256 * @param[in] remote_device This parameter specifies the remote device 1257 * object on which the user is attempting to perform a complete IO 1258 * operation. 1259 * @param[in] io_request This parameter specifies the io request that is 1260 * being completed. 1261 * 1262 * @return This method returns an indication that complete IO operations 1263 * are not allowed. 1264 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1265 */ 1266 static 1267 SCI_STATUS scif_sas_domain_default_complete_high_priority_io_handler( 1268 SCI_BASE_DOMAIN_T * domain, 1269 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1270 SCI_BASE_REQUEST_T * io_request, 1271 void * response_data, 1272 SCI_IO_STATUS completion_status 1273 ) 1274 { 1275 SCIF_LOG_WARNING(( 1276 sci_base_object_get_logger(domain), 1277 SCIF_LOG_OBJECT_DOMAIN, 1278 "Domain:0x%x Device:0x%x State:0x%x complete IO message invalid\n", 1279 domain, remote_device, 1280 sci_base_state_machine_get_state(&domain->state_machine) 1281 )); 1282 1283 return SCI_FAILURE_INVALID_STATE; 1284 } 1285 1286 /** 1287 * @brief This method provides default handling (i.e. returns an error) 1288 * when a user attempts to continue an IO on a domain and a 1289 * continue IO operation is not allowed. 1290 * 1291 * @param[in] domain This parameter specifies the domain object 1292 * on which the user is attempting to perform a continue IO 1293 * operation. 1294 * @param[in] remote_device This parameter specifies the remote device 1295 * object on which the user is attempting to perform a start IO 1296 * operation. 1297 * @param[in] io_request This parameter specifies the io request that is 1298 * being started. 1299 * 1300 * @return This method returns an indication that continue IO operations 1301 * are not allowed. 1302 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1303 */ 1304 static 1305 SCI_STATUS scif_sas_domain_default_continue_io_handler( 1306 SCI_BASE_DOMAIN_T * domain, 1307 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1308 SCI_BASE_REQUEST_T * io_request 1309 ) 1310 { 1311 SCIF_LOG_WARNING(( 1312 sci_base_object_get_logger(domain), 1313 SCIF_LOG_OBJECT_DOMAIN, 1314 "Domain:0x%x Device:0x%x State:0x%x contineu IO message invalid\n", 1315 domain, remote_device, 1316 sci_base_state_machine_get_state(&domain->state_machine) 1317 )); 1318 1319 return SCI_FAILURE_INVALID_STATE; 1320 } 1321 1322 /** 1323 * @brief This method provides default handling (i.e. returns an error) 1324 * when a user attempts to start a task on a domain and a start 1325 * task operation is not allowed. 1326 * 1327 * @param[in] domain This parameter specifies the domain object 1328 * on which the user is attempting to perform a start task 1329 * operation. 1330 * @param[in] remote_device This parameter specifies the remote device 1331 * object on which the user is attempting to perform a start IO 1332 * operation. 1333 * @param[in] task_request This parameter specifies the task request that 1334 * is being started. 1335 * 1336 * @return This method returns an indication that start task operations 1337 * are not allowed. 1338 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1339 */ 1340 static 1341 SCI_STATUS scif_sas_domain_default_start_task_handler( 1342 SCI_BASE_DOMAIN_T * domain, 1343 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1344 SCI_BASE_REQUEST_T * task_request 1345 ) 1346 { 1347 SCIF_LOG_WARNING(( 1348 sci_base_object_get_logger(domain), 1349 SCIF_LOG_OBJECT_DOMAIN, 1350 "Domain:0x%x Device:0x%x State:0x%x start task message invalid\n", 1351 domain, remote_device, 1352 sci_base_state_machine_get_state(&domain->state_machine) 1353 )); 1354 1355 return SCI_FAILURE_INVALID_STATE; 1356 } 1357 1358 /** 1359 * @brief This method provides default handling (i.e. returns an error) 1360 * when a user attempts to complete a task on a domain and a 1361 * complete task operation is not allowed. 1362 * 1363 * @param[in] domain This parameter specifies the domain object 1364 * on which the user is attempting to perform a complete task 1365 * operation. 1366 * @param[in] remote_device This parameter specifies the remote device 1367 * object on which the user is attempting to perform a start IO 1368 * operation. 1369 * @param[in] task_request This parameter specifies the task request that 1370 * is being started. 1371 * 1372 * @return This method returns an indication that complete task operations 1373 * are not allowed. 1374 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1375 */ 1376 static 1377 SCI_STATUS scif_sas_domain_default_complete_task_handler( 1378 SCI_BASE_DOMAIN_T * domain, 1379 SCI_BASE_REMOTE_DEVICE_T * remote_device, 1380 SCI_BASE_REQUEST_T * task_request 1381 ) 1382 { 1383 SCIF_LOG_WARNING(( 1384 sci_base_object_get_logger(domain), 1385 SCIF_LOG_OBJECT_DOMAIN, 1386 "Domain:0x%x Device:0x%x State:0x%x complete task message invalid\n", 1387 domain, remote_device, 1388 sci_base_state_machine_get_state(&domain->state_machine) 1389 )); 1390 1391 return SCI_FAILURE_INVALID_STATE; 1392 } 1393 1394 /** 1395 * @brief This method provides default handling (i.e. returns an error) 1396 * when a remote device start operation completes in a state. 1397 * 1398 * @param[in] domain This parameter specifies the domain object 1399 * on which the remote device start operation is completing. 1400 * @param[in] remote_device This parameter specifies the remote device 1401 * for which the start operation is completing. 1402 * 1403 * @return This method returns an indication that start operation 1404 * completion is not allowed. 1405 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1406 */ 1407 static 1408 SCI_STATUS scif_sas_domain_default_device_start_complete_handler( 1409 SCI_BASE_DOMAIN_T * domain, 1410 SCI_BASE_REMOTE_DEVICE_T * remote_device 1411 ) 1412 { 1413 SCIF_LOG_WARNING(( 1414 sci_base_object_get_logger(domain), 1415 SCIF_LOG_OBJECT_DOMAIN, 1416 "Domain:0x%x Device:0x%x State:0x%x device stop complete message invalid\n", 1417 domain, remote_device, 1418 sci_base_state_machine_get_state(&domain->state_machine) 1419 )); 1420 1421 return SCI_FAILURE_INVALID_STATE; 1422 } 1423 1424 /** 1425 * @brief This method provides default handling (i.e. returns an error) 1426 * when a remote device stop operation completes in a state. 1427 * 1428 * @param[in] domain This parameter specifies the domain object 1429 * on which the remote device stop operation is completing. 1430 * @param[in] remote_device This parameter specifies the remote device 1431 * for which the stop operation is completing. 1432 * 1433 * @return This method returns an indication that stop operation 1434 * completion is not allowed. 1435 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1436 */ 1437 static 1438 SCI_STATUS scif_sas_domain_default_device_stop_complete_handler( 1439 SCI_BASE_DOMAIN_T * domain, 1440 SCI_BASE_REMOTE_DEVICE_T * remote_device 1441 ) 1442 { 1443 SCIF_LOG_WARNING(( 1444 sci_base_object_get_logger(domain), 1445 SCIF_LOG_OBJECT_DOMAIN, 1446 "Domain:0x%x Device:0x%x State:0x%x device stop complete message invalid\n", 1447 domain, remote_device, 1448 sci_base_state_machine_get_state(&domain->state_machine) 1449 )); 1450 1451 return SCI_FAILURE_INVALID_STATE; 1452 } 1453 1454 /** 1455 * @brief This method provides default handling (i.e. returns an error) 1456 * when sci user try to destruct a remote device of this domain. 1457 * 1458 * @param[in] domain This parameter specifies the domain object 1459 * on which the remote device is to be destructed. 1460 * @param[in] remote_device This parameter specifies the remote device 1461 * to be destructed. 1462 * 1463 * @return This method returns an indication that device destruction 1464 * is not allowed. 1465 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 1466 */ 1467 static 1468 SCI_STATUS scif_sas_domain_default_device_destruct_handler( 1469 SCI_BASE_DOMAIN_T * domain, 1470 SCI_BASE_REMOTE_DEVICE_T * remote_device 1471 ) 1472 { 1473 SCIF_LOG_WARNING(( 1474 sci_base_object_get_logger(domain), 1475 SCIF_LOG_OBJECT_DOMAIN, 1476 "Domain:0x%x Device:0x%x State:0x%x device destruct in invalid state\n", 1477 domain, remote_device, 1478 sci_base_state_machine_get_state(&domain->state_machine) 1479 )); 1480 1481 return SCI_FAILURE_INVALID_STATE; 1482 } 1483 1484 1485 /** 1486 * @brief This method provides handling when sci user destruct a remote 1487 * device of this domain in discovering state. Mainly the device 1488 * is removed from domain's remote_device_list. 1489 * 1490 * @param[in] domain This parameter specifies the domain object 1491 * on which the remote device is to be destructed. 1492 * @param[in] remote_device This parameter specifies the remote device 1493 * to be destructed. 1494 * 1495 * @return This method returns a status of the device destruction. 1496 * @retval SCI_SUCCESS This value is returned when a remote device is 1497 * successfully removed from domain. 1498 */ 1499 static 1500 SCI_STATUS scif_sas_domain_discovering_device_destruct_handler( 1501 SCI_BASE_DOMAIN_T * domain, 1502 SCI_BASE_REMOTE_DEVICE_T * remote_device 1503 ) 1504 { 1505 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)domain; 1506 1507 SCIF_LOG_WARNING(( 1508 sci_base_object_get_logger(domain), 1509 SCIF_LOG_OBJECT_DOMAIN, 1510 "Domain:0x%x Device:0x%x State:0x%x device destruct in domain DISCOVERING state\n", 1511 domain, remote_device, 1512 sci_base_state_machine_get_state(&domain->state_machine) 1513 )); 1514 1515 //remove the remote device from domain's remote_device_list 1516 sci_abstract_list_erase( 1517 &(fw_domain->remote_device_list), 1518 remote_device 1519 ); 1520 1521 return SCI_SUCCESS; 1522 } 1523 1524 1525 #define scif_sas_domain_stopped_discover_handler \ 1526 scif_sas_domain_ready_discover_handler 1527 1528 #define scif_sas_domain_default_start_high_priority_io_handler \ 1529 scif_sas_domain_default_start_io_handler 1530 1531 1532 SCI_BASE_DOMAIN_STATE_HANDLER_T 1533 scif_sas_domain_state_handler_table[SCI_BASE_DOMAIN_MAX_STATES] = 1534 { 1535 // SCI_BASE_DOMAIN_STATE_INITIAL 1536 { 1537 scif_sas_domain_default_discover_handler, 1538 scif_sas_domain_default_port_ready_handler, 1539 scif_sas_domain_default_port_not_ready_handler, 1540 scif_sas_domain_default_device_start_complete_handler, 1541 scif_sas_domain_default_device_stop_complete_handler, 1542 scif_sas_domain_default_device_destruct_handler, 1543 scif_sas_domain_default_start_io_handler, 1544 scif_sas_domain_default_start_high_priority_io_handler, 1545 scif_sas_domain_default_complete_io_handler, 1546 scif_sas_domain_default_complete_high_priority_io_handler, 1547 scif_sas_domain_default_continue_io_handler, 1548 scif_sas_domain_default_start_task_handler, 1549 scif_sas_domain_default_complete_task_handler 1550 }, 1551 // SCI_BASE_DOMAIN_STATE_STARTING 1552 { 1553 scif_sas_domain_default_discover_handler, 1554 scif_sas_domain_starting_port_ready_handler, 1555 scif_sas_domain_default_port_not_ready_handler, 1556 scif_sas_domain_default_device_start_complete_handler, 1557 scif_sas_domain_default_device_stop_complete_handler, 1558 scif_sas_domain_default_device_destruct_handler, 1559 scif_sas_domain_default_start_io_handler, 1560 scif_sas_domain_default_start_high_priority_io_handler, 1561 scif_sas_domain_default_complete_io_handler, 1562 scif_sas_domain_default_complete_high_priority_io_handler, 1563 scif_sas_domain_default_continue_io_handler, 1564 scif_sas_domain_default_start_task_handler, 1565 scif_sas_domain_default_complete_task_handler 1566 }, 1567 // SCI_BASE_DOMAIN_STATE_READY 1568 { 1569 scif_sas_domain_ready_discover_handler, 1570 scif_sas_domain_default_port_ready_handler, 1571 scif_sas_domain_ready_port_not_ready_handler, 1572 scif_sas_domain_default_device_start_complete_handler, 1573 scif_sas_domain_default_device_stop_complete_handler, 1574 scif_sas_domain_default_device_destruct_handler, 1575 scif_sas_domain_ready_start_io_handler, 1576 scif_sas_domain_ready_start_high_priority_io_handler, 1577 scif_sas_domain_ready_complete_io_handler, 1578 scif_sas_domain_ready_complete_high_priority_io_handler, 1579 scif_sas_domain_ready_continue_io_handler, 1580 scif_sas_domain_ready_start_task_handler, 1581 scif_sas_domain_ready_complete_task_handler 1582 }, 1583 // SCI_BASE_DOMAIN_STATE_STOPPING 1584 { 1585 scif_sas_domain_default_discover_handler, 1586 scif_sas_domain_default_port_ready_handler, 1587 scif_sas_domain_default_port_not_ready_handler, 1588 scif_sas_domain_default_device_start_complete_handler, 1589 scif_sas_domain_stopping_device_stop_complete_handler, 1590 scif_sas_domain_default_device_destruct_handler, 1591 scif_sas_domain_default_start_io_handler, 1592 scif_sas_domain_default_start_high_priority_io_handler, 1593 scif_sas_domain_stopping_complete_io_handler, 1594 scif_sas_domain_stopping_complete_high_priority_io_handler, 1595 scif_sas_domain_default_continue_io_handler, 1596 scif_sas_domain_default_start_task_handler, 1597 scif_sas_domain_stopping_complete_task_handler 1598 }, 1599 // SCI_BASE_DOMAIN_STATE_STOPPED 1600 { 1601 scif_sas_domain_stopped_discover_handler, 1602 scif_sas_domain_default_port_ready_handler, 1603 scif_sas_domain_default_port_not_ready_handler, 1604 scif_sas_domain_default_device_start_complete_handler, 1605 scif_sas_domain_default_device_stop_complete_handler, 1606 scif_sas_domain_default_device_destruct_handler, 1607 scif_sas_domain_default_start_io_handler, 1608 scif_sas_domain_default_start_high_priority_io_handler, 1609 scif_sas_domain_default_complete_io_handler, 1610 scif_sas_domain_default_complete_high_priority_io_handler, 1611 scif_sas_domain_default_continue_io_handler, 1612 scif_sas_domain_default_start_task_handler, 1613 scif_sas_domain_default_complete_task_handler 1614 }, 1615 // SCI_BASE_DOMAIN_STATE_DISCOVERING 1616 { 1617 scif_sas_domain_default_discover_handler, 1618 scif_sas_domain_default_port_ready_handler, 1619 scif_sas_domain_discovering_port_not_ready_handler, 1620 scif_sas_domain_discovering_device_start_complete_handler, 1621 scif_sas_domain_discovering_device_stop_complete_handler, 1622 scif_sas_domain_discovering_device_destruct_handler, // 1623 scif_sas_domain_default_start_io_handler, 1624 scif_sas_domain_discovering_start_high_priority_io_handler, 1625 scif_sas_domain_discovering_complete_io_handler, 1626 scif_sas_domain_discovering_complete_high_priority_io_handler, // 1627 scif_sas_domain_discovering_continue_io_handler, 1628 scif_sas_domain_discovering_start_task_handler, 1629 scif_sas_domain_discovering_complete_task_handler 1630 } 1631 }; 1632 1633