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