scif_sas_remote_device_ready_substate_handlers.c revision 230557
1314125Sdelphij/*- 296593Smarkm * This file is provided under a dual BSD/GPLv2 license. When using or 396593Smarkm * redistributing this file, you may do so under either license. 4142429Snectar * 596593Smarkm * GPL LICENSE SUMMARY 696593Smarkm * 796593Smarkm * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 896593Smarkm * 996593Smarkm * This program is free software; you can redistribute it and/or modify 1096593Smarkm * it under the terms of version 2 of the GNU General Public License as 1196593Smarkm * published by the Free Software Foundation. 1296593Smarkm * 1396593Smarkm * This program is distributed in the hope that it will be useful, but 1496593Smarkm * WITHOUT ANY WARRANTY; without even the implied warranty of 1596593Smarkm * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1696593Smarkm * General Public License for more details. 1796593Smarkm * 1896593Smarkm * You should have received a copy of the GNU General Public License 1996593Smarkm * along with this program; if not, write to the Free Software 20215698Ssimon * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21215698Ssimon * The full GNU General Public License is included in this distribution 22215698Ssimon * in the file called LICENSE.GPL. 23215698Ssimon * 24215698Ssimon * BSD LICENSE 2596593Smarkm * 2696593Smarkm * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 2796593Smarkm * All rights reserved. 2896593Smarkm * 2996593Smarkm * Redistribution and use in source and binary forms, with or without 3096593Smarkm * modification, are permitted provided that the following conditions 3196593Smarkm * are met: 3296593Smarkm * 3396593Smarkm * * Redistributions of source code must retain the above copyright 3496593Smarkm * notice, this list of conditions and the following disclaimer. 3596593Smarkm * * Redistributions in binary form must reproduce the above copyright 3696593Smarkm * notice, this list of conditions and the following disclaimer in 3796593Smarkm * the documentation and/or other materials provided with the 3896593Smarkm * distribution. 3996593Smarkm * 4096593Smarkm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41276861Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42276861Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 4396593Smarkm * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 4496593Smarkm * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45215698Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46215698Ssimon * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47215698Ssimon * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48215698Ssimon * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49314125Sdelphij * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50215698Ssimon * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51142429Snectar */ 52142429Snectar 53276861Sjkim#include <sys/cdefs.h> 54276861Sjkim__FBSDID("$FreeBSD$"); 55276861Sjkim 5696593Smarkm/** 57314125Sdelphij * @file 58314125Sdelphij * 59314125Sdelphij * @brief This file contains all of the method implementations pertaining 60314125Sdelphij * to the framework remote device READY sub-state handler methods. 61215698Ssimon */ 62314125Sdelphij 63314125Sdelphij#include <dev/isci/scil/scic_remote_device.h> 64314125Sdelphij#include <dev/isci/scil/scic_io_request.h> 65276861Sjkim 66215698Ssimon#include <dev/isci/scil/scif_sas_logger.h> 6796593Smarkm#include <dev/isci/scil/scif_sas_remote_device.h> 6896593Smarkm#include <dev/isci/scil/scif_sas_domain.h> 6996593Smarkm#include <dev/isci/scil/scif_sas_task_request.h> 7096593Smarkm#include <dev/isci/scil/scif_sas_io_request.h> 7196593Smarkm#include <dev/isci/scil/scif_sas_internal_io_request.h> 7296593Smarkm#include <dev/isci/scil/scif_sas_controller.h> 7396593Smarkm#include <dev/isci/scil/sci_abstract_list.h> 7496593Smarkm#include <dev/isci/scil/intel_sat.h> 7596593Smarkm#include <dev/isci/scil/sci_controller.h> 7696593Smarkm 7796593Smarkm//****************************************************************************** 7896593Smarkm//* P R I V A T E M E T H O D S 7996593Smarkm//****************************************************************************** 8096593Smarkm 8196593Smarkm/** 8296593Smarkm * @brief This method implements the behavior common to starting a task mgmt 8396593Smarkm * request. It will change the ready substate to task management. 8496593Smarkm * 8596593Smarkm * @param[in] fw_device This parameter specifies the remote device for 8696593Smarkm * which to complete a request. 8796593Smarkm * @param[in] fw_task This parameter specifies the task management 8896593Smarkm * request being started. 8996593Smarkm * 9096593Smarkm * @return This method returns a value indicating the status of the 9196593Smarkm * start operation. 9296593Smarkm */ 9396593Smarkmstatic 9496593SmarkmSCI_STATUS scif_sas_remote_device_start_task_request( 9596593Smarkm SCIF_SAS_REMOTE_DEVICE_T * fw_device, 9696593Smarkm SCIF_SAS_TASK_REQUEST_T * fw_task 9796593Smarkm) 9896593Smarkm{ 9996593Smarkm // Transition into the TASK MGMT substate if not already in it. 10096593Smarkm if (fw_device->ready_substate_machine.current_state_id 10196593Smarkm != SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT) 10296593Smarkm { 10396593Smarkm sci_base_state_machine_change_state( 10496593Smarkm &fw_device->ready_substate_machine, 10596593Smarkm SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT 10696593Smarkm ); 10796593Smarkm } 10896593Smarkm 10996593Smarkm fw_device->request_count++; 11096593Smarkm fw_device->task_request_count++; 11196593Smarkm 11296593Smarkm return SCI_SUCCESS; 11396593Smarkm} 11496593Smarkm 11596593Smarkm//****************************************************************************** 11696593Smarkm//* R E A D Y O P E R A T I O N A L H A N D L E R S 11796593Smarkm//****************************************************************************** 11896593Smarkm 11996593Smarkm/** 12096593Smarkm * @brief This method provides OPERATIONAL sub-state specific handling for 12196593Smarkm * when the core remote device object issues a device not ready 12296593Smarkm * notification. 12396593Smarkm * 12496593Smarkm * @param[in] remote_device This parameter specifies the remote device 12596593Smarkm * object for which the notification occurred. 12696593Smarkm * 12796593Smarkm * @return none. 12896593Smarkm */ 129142429Snectarstatic 13096593Smarkmvoid scif_sas_remote_device_ready_operational_not_ready_handler( 131100946Snectar SCIF_SAS_REMOTE_DEVICE_T * fw_device, 132314125Sdelphij U32 reason_code 133215698Ssimon) 134215698Ssimon{ 135215698Ssimon if (reason_code == SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED) 136215698Ssimon { 13796593Smarkm sci_base_state_machine_change_state( 13896593Smarkm &fw_device->ready_substate_machine, 13996593Smarkm SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 14096593Smarkm ); 14196593Smarkm } 14296593Smarkm else 143215698Ssimon { 14496593Smarkm // Even though we are in the OPERATIONAL state, the core remote device is not 145215698Ssimon // ready. As a result, we process user requests/events as if we were 14696593Smarkm // stopping the framework remote device. 147215698Ssimon sci_base_state_machine_change_state( 14896593Smarkm &fw_device->ready_substate_machine, 149215698Ssimon SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED 15096593Smarkm ); 151215698Ssimon } 15296593Smarkm} 15396593Smarkm 15496593Smarkm/** 15596593Smarkm * @brief This method provides TASK MGMT sub-state specific handling for when 156160819Ssimon * the core remote device object issues a device not ready notification. 15796593Smarkm * 15896593Smarkm * @param[in] remote_device This parameter specifies the remote device 15996593Smarkm * object for which the notification occurred. 16096593Smarkm * 16196593Smarkm * @return none. 16296593Smarkm */ 16396593Smarkmstatic 16496593Smarkmvoid scif_sas_remote_device_ready_task_management_not_ready_handler( 16596593Smarkm SCIF_SAS_REMOTE_DEVICE_T * fw_device, 16696593Smarkm U32 reason_code 16796593Smarkm) 16896593Smarkm{ 16996593Smarkm //do nothing. Don't need to go to suspended substate. 170142429Snectar} 17196593Smarkm 17296593Smarkm/** 17396593Smarkm * @brief This method provides OPERATIONAL sub-state specific handling for 17496593Smarkm * when the remote device is being stopped by the framework. 17596593Smarkm * 176142429Snectar * @param[in] remote_device This parameter specifies the remote device 17796593Smarkm * object for which the stop operation is being requested. 17896593Smarkm * 17996593Smarkm * @return This method returns an indication as to whether the failure 18096593Smarkm * operation completed successfully. 18196593Smarkm */ 182static 183SCI_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 */ 209static 210SCI_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 */ 232static 233SCI_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 */ 269static 270SCI_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 */ 304SCI_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 */ 330static 331SCI_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 */ 365static 366SCI_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 */ 391static 392SCI_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 */ 486SCI_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 */ 513static 514SCI_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 */ 560SCI_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 */ 601static 602void 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 */ 625SCI_STATUS 626scif_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 687SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T 688scif_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