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