1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0 3 * 4 * This file is provided under a dual BSD/GPLv2 license. When using or 5 * redistributing this file, you may do so under either license. 6 * 7 * GPL LICENSE SUMMARY 8 * 9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of version 2 of the GNU General Public License as 13 * published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 23 * The full GNU General Public License is included in this distribution 24 * in the file called LICENSE.GPL. 25 * 26 * BSD LICENSE 27 * 28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 34 * 35 * * Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * * Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in 39 * the documentation and/or other materials provided with the 40 * distribution. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 */ 54 55 #include <sys/cdefs.h> 56 __FBSDID("$FreeBSD$"); 57 58 /** 59 * @file 60 * 61 * @brief This file contains all of the method implementations pertaining 62 * to the framework remote device READY sub-state handler methods. 63 */ 64 65 #include <dev/isci/scil/scic_remote_device.h> 66 #include <dev/isci/scil/scic_io_request.h> 67 68 #include <dev/isci/scil/scif_sas_logger.h> 69 #include <dev/isci/scil/scif_sas_remote_device.h> 70 #include <dev/isci/scil/scif_sas_domain.h> 71 #include <dev/isci/scil/scif_sas_task_request.h> 72 #include <dev/isci/scil/scif_sas_io_request.h> 73 #include <dev/isci/scil/scif_sas_internal_io_request.h> 74 #include <dev/isci/scil/scif_sas_controller.h> 75 #include <dev/isci/scil/sci_abstract_list.h> 76 #include <dev/isci/scil/intel_sat.h> 77 #include <dev/isci/scil/sci_controller.h> 78 79 //****************************************************************************** 80 //* P R I V A T E M E T H O D S 81 //****************************************************************************** 82 83 /** 84 * @brief This method implements the behavior common to starting a task mgmt 85 * request. It will change the ready substate to task management. 86 * 87 * @param[in] fw_device This parameter specifies the remote device for 88 * which to complete a request. 89 * @param[in] fw_task This parameter specifies the task management 90 * request being started. 91 * 92 * @return This method returns a value indicating the status of the 93 * start operation. 94 */ 95 static 96 SCI_STATUS scif_sas_remote_device_start_task_request( 97 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 98 SCIF_SAS_TASK_REQUEST_T * fw_task 99 ) 100 { 101 // Transition into the TASK MGMT substate if not already in it. 102 if (fw_device->ready_substate_machine.current_state_id 103 != SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT) 104 { 105 sci_base_state_machine_change_state( 106 &fw_device->ready_substate_machine, 107 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT 108 ); 109 } 110 111 fw_device->request_count++; 112 fw_device->task_request_count++; 113 114 return SCI_SUCCESS; 115 } 116 117 //****************************************************************************** 118 //* R E A D Y O P E R A T I O N A L H A N D L E R S 119 //****************************************************************************** 120 121 /** 122 * @brief This method provides OPERATIONAL sub-state specific handling for 123 * when the core remote device object issues a device not ready 124 * notification. 125 * 126 * @param[in] remote_device This parameter specifies the remote device 127 * object for which the notification occurred. 128 * 129 * @return none. 130 */ 131 static 132 void scif_sas_remote_device_ready_operational_not_ready_handler( 133 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 134 U32 reason_code 135 ) 136 { 137 if (reason_code == SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED) 138 { 139 sci_base_state_machine_change_state( 140 &fw_device->ready_substate_machine, 141 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 142 ); 143 } 144 else 145 { 146 // Even though we are in the OPERATIONAL state, the core remote device is not 147 // ready. As a result, we process user requests/events as if we were 148 // stopping the framework remote device. 149 sci_base_state_machine_change_state( 150 &fw_device->ready_substate_machine, 151 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED 152 ); 153 } 154 } 155 156 /** 157 * @brief This method provides TASK MGMT sub-state specific handling for when 158 * the core remote device object issues a device not ready notification. 159 * 160 * @param[in] remote_device This parameter specifies the remote device 161 * object for which the notification occurred. 162 * 163 * @return none. 164 */ 165 static 166 void scif_sas_remote_device_ready_task_management_not_ready_handler( 167 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 168 U32 reason_code 169 ) 170 { 171 //do nothing. Don't need to go to suspended substate. 172 } 173 174 /** 175 * @brief This method provides OPERATIONAL sub-state specific handling for 176 * when the remote device is being stopped by the framework. 177 * 178 * @param[in] remote_device This parameter specifies the remote device 179 * object for which the stop operation is being requested. 180 * 181 * @return This method returns an indication as to whether the failure 182 * operation completed successfully. 183 */ 184 static 185 SCI_STATUS scif_sas_remote_device_ready_operational_stop_handler( 186 SCI_BASE_REMOTE_DEVICE_T * remote_device 187 ) 188 { 189 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) 190 remote_device; 191 192 sci_base_state_machine_change_state( 193 &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 194 ); 195 196 return fw_device->operation_status; 197 } 198 199 /** 200 * @brief This method provides OPERATIONAL sub-state specific handling for 201 * when the user attempts to destruct the remote device. In 202 * the READY state the framework must first stop the device 203 * before destructing it. 204 * 205 * @param[in] remote_device This parameter specifies the remote device 206 * object for which the framework is attempting to start. 207 * 208 * @return This method returns an indication as to whether the destruct 209 * operation completed successfully. 210 */ 211 static 212 SCI_STATUS scif_sas_remote_device_ready_operational_destruct_handler( 213 SCI_BASE_REMOTE_DEVICE_T * remote_device 214 ) 215 { 216 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) 217 remote_device; 218 219 fw_device->destruct_when_stopped = TRUE; 220 221 return (fw_device->state_handlers->parent.stop_handler(&fw_device->parent)); 222 } 223 224 /** 225 * @brief This method provides OPERATIONAL sub-state specific handling for 226 * when the remote device undergoes a failure condition. 227 * 228 * @param[in] remote_device This parameter specifies the remote device 229 * object for which the failure condition occurred. 230 * 231 * @return This method returns an indication as to whether the failure 232 * operation completed successfully. 233 */ 234 static 235 SCI_STATUS scif_sas_remote_device_ready_operational_fail_handler( 236 SCI_BASE_REMOTE_DEVICE_T * remote_device 237 ) 238 { 239 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) 240 remote_device; 241 242 SCIF_LOG_WARNING(( 243 sci_base_object_get_logger(fw_device), 244 SCIF_LOG_OBJECT_REMOTE_DEVICE, 245 "RemoteDevice:0x%x ready device failed\n", 246 fw_device 247 )); 248 249 sci_base_state_machine_change_state( 250 &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_FAILED 251 ); 252 253 /// @todo Fix the return code handling. 254 return SCI_FAILURE; 255 } 256 257 /** 258 * @brief This method provides OPERATIONAL sub-state specific handling for 259 * when a user attempts to start an IO request on a remote 260 * device. 261 * 262 * @param[in] remote_device This parameter specifies the remote device 263 * object on which the user is attempting to perform a start 264 * IO operation. 265 * @param[in] io_request This parameter specifies the IO request to be 266 * started. 267 * 268 * @return This method returns an indication as to whether the IO request 269 * started successfully. 270 */ 271 static 272 SCI_STATUS scif_sas_remote_device_ready_operational_start_io_handler( 273 SCI_BASE_REMOTE_DEVICE_T * remote_device, 274 SCI_BASE_REQUEST_T * io_request 275 ) 276 { 277 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 278 remote_device; 279 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) io_request; 280 SCI_STATUS status; 281 282 status = fw_io->parent.state_handlers->start_handler(&fw_io->parent.parent); 283 284 if (status == SCI_SUCCESS) 285 { 286 fw_device->request_count++; 287 } 288 289 return status; 290 } 291 292 /** 293 * @brief This method provides OPERATIONAL sub-state specific handling for 294 * when a user attempts to start an IO request on a remote 295 * device. 296 * 297 * @param[in] remote_device This parameter specifies the remote device 298 * object on which the user is attempting to perform a complete 299 * IO operation. 300 * @param[in] io_request This parameter specifies the IO request to 301 * be completed. 302 * 303 * @return This method returns an indication as to whether the IO request 304 * completed successfully. 305 */ 306 SCI_STATUS scif_sas_remote_device_ready_operational_complete_io_handler( 307 SCI_BASE_REMOTE_DEVICE_T * remote_device, 308 SCI_BASE_REQUEST_T * io_request 309 ) 310 { 311 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 312 remote_device; 313 fw_device->request_count--; 314 return SCI_SUCCESS; 315 } 316 317 318 /** 319 * @brief This method provides OPERATIONAL sub-state specific handling for 320 * when a user attempts to start an IO request on a remote 321 * device. 322 * 323 * @param[in] remote_device This parameter specifies the remote device 324 * object on which the user is attempting to perform a complete 325 * IO operation. 326 * @param[in] io_request This parameter specifies the IO request to 327 * be completed. 328 * 329 * @return This method returns an indication as to whether the IO request 330 * completed successfully. 331 */ 332 static 333 SCI_STATUS scif_sas_remote_device_ready_operational_complete_high_priority_io_handler( 334 SCI_BASE_REMOTE_DEVICE_T * remote_device, 335 SCI_BASE_REQUEST_T * io_request, 336 void * response_data, 337 SCI_IO_STATUS completion_status 338 ) 339 { 340 SCIF_LOG_WARNING(( 341 sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 342 SCIF_LOG_OBJECT_REMOTE_DEVICE, 343 "RemoteDevice:0x%x State:0x%x invalid state to complete high priority IO\n", 344 remote_device, 345 sci_base_state_machine_get_state( 346 &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 347 )); 348 349 return SCI_FAILURE_INVALID_STATE; 350 } 351 352 353 /** 354 * @brief This method provides OPERATIONAL sub-state specific handling for when 355 * the framework attempts to continue an IO request on a remote 356 * device. 357 * 358 * @param[in] remote_device This parameter specifies the remote device 359 * object on which the user is attempting to perform a continue 360 * IO operation. 361 * @param[in] io_request This parameter specifies the IO request to 362 * be continued. 363 * 364 * @return This method returns an indication as to whether the IO request 365 * completed successfully. 366 */ 367 static 368 SCI_STATUS scif_sas_remote_device_ready_operational_continue_io_handler( 369 SCI_BASE_REMOTE_DEVICE_T * remote_device, 370 SCI_BASE_REQUEST_T * io_request 371 ) 372 { 373 /// @todo Fix the return code handling. 374 return SCI_FAILURE; 375 } 376 377 /** 378 * @brief This method provides OPERATIONAL sub-state specific handling for 379 * when a user attempts to start a task management request on 380 * a remote device. This includes terminating all of the affected 381 * ongoing IO requests (i.e. aborting them in the silicon) and then 382 * issuing the task management request to the silicon. 383 * 384 * @param[in] remote_device This parameter specifies the remote device 385 * object on which the user is attempting to perform a start 386 * task operation. 387 * @param[in] task_request This parameter specifies the task management 388 * request to be started. 389 * 390 * @return This method returns an indication as to whether the task 391 * management request started successfully. 392 */ 393 static 394 SCI_STATUS scif_sas_remote_device_ready_operational_start_task_handler( 395 SCI_BASE_REMOTE_DEVICE_T * remote_device, 396 SCI_BASE_REQUEST_T * task_request 397 ) 398 { 399 SCI_STATUS status = SCI_FAILURE; 400 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 401 remote_device; 402 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*) 403 task_request; 404 U8 task_function = 405 scif_sas_task_request_get_function(fw_task); 406 407 SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; 408 409 scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); 410 if ( dev_protocols.u.bits.attached_ssp_target 411 || dev_protocols.u.bits.attached_stp_target) 412 { 413 // //NOTE: For STP/SATA targets we currently terminate all requests for 414 // any type of task management. 415 if ( (task_function == SCI_SAS_ABORT_TASK_SET) 416 || (task_function == SCI_SAS_CLEAR_TASK_SET) 417 || (task_function == SCI_SAS_LOGICAL_UNIT_RESET) 418 || (task_function == SCI_SAS_I_T_NEXUS_RESET) 419 || (task_function == SCI_SAS_HARD_RESET) ) 420 { 421 // Terminate all of the requests in the silicon for this device. 422 scif_sas_domain_terminate_requests( 423 fw_device->domain, fw_device, NULL, fw_task 424 ); 425 426 status = scif_sas_remote_device_start_task_request(fw_device, fw_task); 427 } 428 else if ( (task_function == SCI_SAS_CLEAR_ACA) 429 || (task_function == SCI_SAS_QUERY_TASK) 430 || (task_function == SCI_SAS_QUERY_TASK_SET) 431 || (task_function == SCI_SAS_QUERY_ASYNCHRONOUS_EVENT) ) 432 { 433 ASSERT(!dev_protocols.u.bits.attached_stp_target); 434 status = scif_sas_remote_device_start_task_request(fw_device, fw_task); 435 } 436 else if (task_function == SCI_SAS_ABORT_TASK) 437 { 438 SCIF_SAS_REQUEST_T * fw_request 439 = scif_sas_domain_get_request_by_io_tag( 440 fw_device->domain, fw_task->io_tag_to_manage 441 ); 442 443 // Determine if the request being aborted was found. 444 if (fw_request != NULL) 445 { 446 scif_sas_domain_terminate_requests( 447 fw_device->domain, fw_device, fw_request, fw_task 448 ); 449 450 status = scif_sas_remote_device_start_task_request( 451 fw_device, fw_task 452 ); 453 } 454 else 455 status = SCI_FAILURE_INVALID_IO_TAG; 456 } 457 } 458 else 459 status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; 460 461 if (status != SCI_SUCCESS) 462 { 463 SCIF_LOG_ERROR(( 464 sci_base_object_get_logger(fw_device), 465 SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 466 "Controller:0x%x TaskRequest:0x%x Status:0x%x start task failure\n", 467 fw_device, fw_task, status 468 )); 469 } 470 471 return status; 472 } 473 474 /** 475 * @brief This method provides OPERATIONAL sub-state specific handling for 476 * when a user attempts to complete a task management request on 477 * a remote device. 478 * 479 * @param[in] remote_device This parameter specifies the remote device object 480 * on which the user is attempting to perform a complete task 481 * operation. 482 * @param[in] task_request This parameter specifies the task management 483 * request to be completed. 484 * 485 * @return This method returns an indication as to whether the task 486 * management request succeeded. 487 */ 488 SCI_STATUS scif_sas_remote_device_ready_operational_complete_task_handler( 489 SCI_BASE_REMOTE_DEVICE_T * remote_device, 490 SCI_BASE_REQUEST_T * task_request 491 ) 492 { 493 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 494 remote_device; 495 fw_device->request_count--; 496 fw_device->task_request_count--; 497 498 return SCI_SUCCESS; 499 } 500 501 /** 502 * @brief This method provides OPERATIONAL sub-state specific handling for 503 * when a user attempts to start a high priority IO request on a remote 504 * device. 505 * 506 * @param[in] remote_device This parameter specifies the remote device 507 * object on which the user is attempting to perform a start 508 * IO operation. 509 * @param[in] io_request This parameter specifies the IO request to be 510 * started. 511 * 512 * @return This method returns an indication as to whether the IO request 513 * started successfully. 514 */ 515 static 516 SCI_STATUS scif_sas_remote_device_ready_operational_start_high_priority_io_handler( 517 SCI_BASE_REMOTE_DEVICE_T * remote_device, 518 SCI_BASE_REQUEST_T * io_request 519 ) 520 { 521 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 522 remote_device; 523 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) io_request; 524 525 SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; 526 527 scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); 528 529 if (dev_protocols.u.bits.attached_smp_target) 530 { 531 //transit to task management state for smp request phase. 532 if (fw_device->ready_substate_machine.current_state_id 533 != SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT) 534 { 535 sci_base_state_machine_change_state( 536 &fw_device->ready_substate_machine, 537 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT 538 ); 539 } 540 } 541 542 fw_device->request_count++; 543 544 return fw_io->parent.state_handlers->start_handler(&fw_io->parent.parent); 545 } 546 547 548 /** 549 * @brief This method provides TASK MANAGEMENT sub-state specific handling for 550 * when a user attempts to complete a task management request on 551 * a remote device. 552 * 553 * @param[in] remote_device This parameter specifies the remote device object 554 * on which the user is attempting to perform a complete task 555 * operation. 556 * @param[in] task_request This parameter specifies the task management 557 * request to be completed. 558 * 559 * @return This method returns an indication as to whether the task 560 * management request succeeded. 561 */ 562 SCI_STATUS scif_sas_remote_device_ready_task_management_complete_task_handler( 563 SCI_BASE_REMOTE_DEVICE_T * remote_device, 564 SCI_BASE_REQUEST_T * task_request 565 ) 566 { 567 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 568 remote_device; 569 570 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T *) 571 task_request; 572 573 fw_device->request_count--; 574 fw_device->task_request_count--; 575 576 // All existing task management requests and all of the IO requests 577 // affectected by the task management request must complete before 578 // the remote device can transition back into the READY / OPERATIONAL 579 // state. 580 if ( (fw_device->task_request_count == 0) 581 && (fw_task->affected_request_count == 0) ) 582 { 583 sci_base_state_machine_change_state( 584 &fw_device->ready_substate_machine, 585 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL 586 ); 587 } 588 589 return SCI_SUCCESS; 590 } 591 592 /** 593 * @brief This method provides SUSPENDED sub-state specific handling for 594 * when the core remote device object issues a device ready 595 * notification. This effectively causes the framework remote 596 * device to transition back into the OPERATIONAL state. 597 * 598 * @param[in] remote_device This parameter specifies the remote device 599 * object for which the notification occurred. 600 * 601 * @return none. 602 */ 603 static 604 void scif_sas_remote_device_ready_suspended_ready_handler( 605 SCIF_SAS_REMOTE_DEVICE_T * fw_device 606 ) 607 { 608 sci_base_state_machine_change_state( 609 &fw_device->ready_substate_machine, 610 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL 611 ); 612 } 613 614 615 /** 616 * @brief This handler is currently solely used by smp remote device for 617 * discovering. 618 * 619 * @param[in] remote_device This parameter specifies the remote device 620 * object on which the user is attempting to perform a complete high 621 * priority IO operation. 622 * @param[in] io_request This parameter specifies the high priority IO request 623 * to be completed. 624 * 625 * @return SCI_STATUS indicate whether the io complete successfully. 626 */ 627 SCI_STATUS 628 scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler( 629 SCI_BASE_REMOTE_DEVICE_T * remote_device, 630 SCI_BASE_REQUEST_T * io_request, 631 void * response_data, 632 SCI_IO_STATUS completion_status 633 ) 634 { 635 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 636 remote_device; 637 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) io_request; 638 SCI_STATUS status = SCI_SUCCESS; 639 SCIC_TRANSPORT_PROTOCOL protocol; 640 641 SCIF_LOG_TRACE(( 642 sci_base_object_get_logger(remote_device), 643 SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_IO_REQUEST, 644 "scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 645 remote_device, io_request, response_data, completion_status 646 )); 647 648 fw_device->request_count--; 649 650 // we are back to ready operational sub state here. 651 sci_base_state_machine_change_state( 652 &fw_device->ready_substate_machine, 653 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL 654 ); 655 656 protocol = scic_io_request_get_protocol(fw_request->core_object); 657 658 // If this request was an SMP initiator request we created, then 659 // decode the response. 660 if (protocol == SCIC_SMP_PROTOCOL) 661 { 662 if (completion_status != SCI_IO_FAILURE_TERMINATED) 663 { 664 status = scif_sas_smp_remote_device_decode_smp_response( 665 fw_device, fw_request, response_data, completion_status 666 ); 667 } 668 else 669 scif_sas_smp_remote_device_terminated_request_handler(fw_device, fw_request); 670 } 671 else 672 { 673 // Currently, there are only internal SMP requests. So, default work 674 // is simply to clean up the internal request. 675 if (fw_request->is_internal == TRUE) 676 { 677 scif_sas_internal_io_request_complete( 678 fw_device->domain->controller, 679 (SCIF_SAS_INTERNAL_IO_REQUEST_T *)fw_request, 680 SCI_SUCCESS 681 ); 682 } 683 } 684 685 return status; 686 } 687 688 689 SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T 690 scif_sas_remote_device_ready_substate_handler_table[] = 691 { 692 // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL 693 { 694 { 695 scif_sas_remote_device_default_start_handler, 696 scif_sas_remote_device_ready_operational_stop_handler, 697 scif_sas_remote_device_ready_operational_fail_handler, 698 scif_sas_remote_device_ready_operational_destruct_handler, 699 scif_sas_remote_device_default_reset_handler, 700 scif_sas_remote_device_default_reset_complete_handler, 701 scif_sas_remote_device_ready_operational_start_io_handler, 702 scif_sas_remote_device_ready_operational_complete_io_handler, 703 scif_sas_remote_device_ready_operational_continue_io_handler, 704 scif_sas_remote_device_ready_operational_start_task_handler, 705 scif_sas_remote_device_ready_operational_complete_task_handler 706 }, 707 scif_sas_remote_device_default_start_complete_handler, 708 scif_sas_remote_device_default_stop_complete_handler, 709 scif_sas_remote_device_default_ready_handler, 710 scif_sas_remote_device_ready_operational_not_ready_handler, 711 scif_sas_remote_device_ready_operational_start_high_priority_io_handler, // 712 scif_sas_remote_device_ready_operational_complete_high_priority_io_handler 713 }, 714 // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED 715 { 716 { 717 scif_sas_remote_device_default_start_handler, 718 scif_sas_remote_device_ready_operational_stop_handler, 719 scif_sas_remote_device_ready_operational_fail_handler, 720 scif_sas_remote_device_ready_operational_destruct_handler, 721 scif_sas_remote_device_default_reset_handler, 722 scif_sas_remote_device_default_reset_complete_handler, 723 scif_sas_remote_device_default_start_io_handler, 724 scif_sas_remote_device_ready_operational_complete_io_handler, 725 scif_sas_remote_device_default_continue_io_handler, 726 scif_sas_remote_device_ready_operational_start_task_handler, 727 scif_sas_remote_device_ready_operational_complete_task_handler 728 }, 729 scif_sas_remote_device_default_start_complete_handler, 730 scif_sas_remote_device_default_stop_complete_handler, 731 scif_sas_remote_device_ready_suspended_ready_handler, 732 scif_sas_remote_device_default_not_ready_handler, 733 scif_sas_remote_device_default_start_io_handler, 734 scif_sas_remote_device_ready_operational_complete_high_priority_io_handler 735 }, 736 // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT 737 { 738 { 739 scif_sas_remote_device_default_start_handler, 740 scif_sas_remote_device_ready_operational_stop_handler, 741 scif_sas_remote_device_ready_operational_fail_handler, 742 scif_sas_remote_device_ready_operational_destruct_handler, 743 scif_sas_remote_device_default_reset_handler, 744 scif_sas_remote_device_default_reset_complete_handler, 745 scif_sas_remote_device_default_start_io_handler, 746 scif_sas_remote_device_ready_operational_complete_io_handler, 747 scif_sas_remote_device_ready_operational_continue_io_handler, 748 scif_sas_remote_device_ready_operational_start_task_handler, 749 scif_sas_remote_device_ready_task_management_complete_task_handler 750 }, 751 scif_sas_remote_device_default_start_complete_handler, 752 scif_sas_remote_device_default_stop_complete_handler, 753 scif_sas_remote_device_default_ready_handler, 754 scif_sas_remote_device_ready_task_management_not_ready_handler, 755 scif_sas_remote_device_ready_operational_start_high_priority_io_handler, 756 scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler 757 }, 758 // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 759 { 760 { 761 scif_sas_remote_device_default_start_handler, 762 scif_sas_remote_device_ready_operational_stop_handler, 763 scif_sas_remote_device_ready_operational_fail_handler, 764 scif_sas_remote_device_ready_operational_destruct_handler, 765 scif_sas_remote_device_default_reset_handler, 766 scif_sas_remote_device_default_reset_complete_handler, 767 scif_sas_remote_device_default_start_io_handler, 768 scif_sas_remote_device_ready_operational_complete_io_handler, 769 scif_sas_remote_device_default_continue_io_handler, 770 scif_sas_remote_device_ready_operational_start_task_handler, 771 scif_sas_remote_device_ready_operational_complete_task_handler 772 }, 773 scif_sas_remote_device_default_start_complete_handler, 774 scif_sas_remote_device_default_stop_complete_handler, 775 scif_sas_remote_device_ready_suspended_ready_handler, 776 scif_sas_remote_device_default_not_ready_handler, 777 scif_sas_remote_device_default_start_io_handler, 778 scif_sas_remote_device_ready_operational_complete_high_priority_io_handler 779 }, 780 }; 781 782