1230557Sjimharris/*- 2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license. When using or 3230557Sjimharris * redistributing this file, you may do so under either license. 4230557Sjimharris * 5230557Sjimharris * GPL LICENSE SUMMARY 6230557Sjimharris * 7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8230557Sjimharris * 9230557Sjimharris * This program is free software; you can redistribute it and/or modify 10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as 11230557Sjimharris * published by the Free Software Foundation. 12230557Sjimharris * 13230557Sjimharris * This program is distributed in the hope that it will be useful, but 14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of 15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16230557Sjimharris * General Public License for more details. 17230557Sjimharris * 18230557Sjimharris * You should have received a copy of the GNU General Public License 19230557Sjimharris * along with this program; if not, write to the Free Software 20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21230557Sjimharris * The full GNU General Public License is included in this distribution 22230557Sjimharris * in the file called LICENSE.GPL. 23230557Sjimharris * 24230557Sjimharris * BSD LICENSE 25230557Sjimharris * 26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27230557Sjimharris * All rights reserved. 28230557Sjimharris * 29230557Sjimharris * Redistribution and use in source and binary forms, with or without 30230557Sjimharris * modification, are permitted provided that the following conditions 31230557Sjimharris * are met: 32230557Sjimharris * 33230557Sjimharris * * Redistributions of source code must retain the above copyright 34230557Sjimharris * notice, this list of conditions and the following disclaimer. 35230557Sjimharris * * Redistributions in binary form must reproduce the above copyright 36230557Sjimharris * notice, this list of conditions and the following disclaimer in 37230557Sjimharris * the documentation and/or other materials provided with the 38230557Sjimharris * distribution. 39230557Sjimharris * 40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51230557Sjimharris */ 52230557Sjimharris 53230557Sjimharris#include <sys/cdefs.h> 54230557Sjimharris__FBSDID("$FreeBSD$"); 55230557Sjimharris 56230557Sjimharris/** 57230557Sjimharris * @file 58230557Sjimharris * 59230557Sjimharris * @brief This file contains all of the method implementations pertaining 60230557Sjimharris * to the framework remote device READY sub-state handler methods. 61230557Sjimharris */ 62230557Sjimharris 63230557Sjimharris#include <dev/isci/scil/scic_remote_device.h> 64230557Sjimharris#include <dev/isci/scil/scic_io_request.h> 65230557Sjimharris 66230557Sjimharris#include <dev/isci/scil/scif_sas_logger.h> 67230557Sjimharris#include <dev/isci/scil/scif_sas_remote_device.h> 68230557Sjimharris#include <dev/isci/scil/scif_sas_domain.h> 69230557Sjimharris#include <dev/isci/scil/scif_sas_task_request.h> 70230557Sjimharris#include <dev/isci/scil/scif_sas_io_request.h> 71230557Sjimharris#include <dev/isci/scil/scif_sas_internal_io_request.h> 72230557Sjimharris#include <dev/isci/scil/scif_sas_controller.h> 73230557Sjimharris#include <dev/isci/scil/sci_abstract_list.h> 74230557Sjimharris#include <dev/isci/scil/intel_sat.h> 75230557Sjimharris#include <dev/isci/scil/sci_controller.h> 76230557Sjimharris 77230557Sjimharris//****************************************************************************** 78230557Sjimharris//* P R I V A T E M E T H O D S 79230557Sjimharris//****************************************************************************** 80230557Sjimharris 81230557Sjimharris/** 82230557Sjimharris * @brief This method implements the behavior common to starting a task mgmt 83230557Sjimharris * request. It will change the ready substate to task management. 84230557Sjimharris * 85230557Sjimharris * @param[in] fw_device This parameter specifies the remote device for 86230557Sjimharris * which to complete a request. 87230557Sjimharris * @param[in] fw_task This parameter specifies the task management 88230557Sjimharris * request being started. 89230557Sjimharris * 90230557Sjimharris * @return This method returns a value indicating the status of the 91230557Sjimharris * start operation. 92230557Sjimharris */ 93230557Sjimharrisstatic 94230557SjimharrisSCI_STATUS scif_sas_remote_device_start_task_request( 95230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 96230557Sjimharris SCIF_SAS_TASK_REQUEST_T * fw_task 97230557Sjimharris) 98230557Sjimharris{ 99230557Sjimharris // Transition into the TASK MGMT substate if not already in it. 100230557Sjimharris if (fw_device->ready_substate_machine.current_state_id 101230557Sjimharris != SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT) 102230557Sjimharris { 103230557Sjimharris sci_base_state_machine_change_state( 104230557Sjimharris &fw_device->ready_substate_machine, 105230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT 106230557Sjimharris ); 107230557Sjimharris } 108230557Sjimharris 109230557Sjimharris fw_device->request_count++; 110230557Sjimharris fw_device->task_request_count++; 111230557Sjimharris 112230557Sjimharris return SCI_SUCCESS; 113230557Sjimharris} 114230557Sjimharris 115230557Sjimharris//****************************************************************************** 116230557Sjimharris//* R E A D Y O P E R A T I O N A L H A N D L E R S 117230557Sjimharris//****************************************************************************** 118230557Sjimharris 119230557Sjimharris/** 120230557Sjimharris * @brief This method provides OPERATIONAL sub-state specific handling for 121230557Sjimharris * when the core remote device object issues a device not ready 122230557Sjimharris * notification. 123230557Sjimharris * 124230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 125230557Sjimharris * object for which the notification occurred. 126230557Sjimharris * 127230557Sjimharris * @return none. 128230557Sjimharris */ 129230557Sjimharrisstatic 130230557Sjimharrisvoid scif_sas_remote_device_ready_operational_not_ready_handler( 131230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 132230557Sjimharris U32 reason_code 133230557Sjimharris) 134230557Sjimharris{ 135230557Sjimharris if (reason_code == SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED) 136230557Sjimharris { 137230557Sjimharris sci_base_state_machine_change_state( 138230557Sjimharris &fw_device->ready_substate_machine, 139230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 140230557Sjimharris ); 141230557Sjimharris } 142230557Sjimharris else 143230557Sjimharris { 144230557Sjimharris // Even though we are in the OPERATIONAL state, the core remote device is not 145230557Sjimharris // ready. As a result, we process user requests/events as if we were 146230557Sjimharris // stopping the framework remote device. 147230557Sjimharris sci_base_state_machine_change_state( 148230557Sjimharris &fw_device->ready_substate_machine, 149230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED 150230557Sjimharris ); 151230557Sjimharris } 152230557Sjimharris} 153230557Sjimharris 154230557Sjimharris/** 155230557Sjimharris * @brief This method provides TASK MGMT sub-state specific handling for when 156230557Sjimharris * the core remote device object issues a device not ready notification. 157230557Sjimharris * 158230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 159230557Sjimharris * object for which the notification occurred. 160230557Sjimharris * 161230557Sjimharris * @return none. 162230557Sjimharris */ 163230557Sjimharrisstatic 164230557Sjimharrisvoid scif_sas_remote_device_ready_task_management_not_ready_handler( 165230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 166230557Sjimharris U32 reason_code 167230557Sjimharris) 168230557Sjimharris{ 169230557Sjimharris //do nothing. Don't need to go to suspended substate. 170230557Sjimharris} 171230557Sjimharris 172230557Sjimharris/** 173230557Sjimharris * @brief This method provides OPERATIONAL sub-state specific handling for 174230557Sjimharris * when the remote device is being stopped by the framework. 175230557Sjimharris * 176230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 177230557Sjimharris * object for which the stop operation is being requested. 178230557Sjimharris * 179230557Sjimharris * @return This method returns an indication as to whether the failure 180230557Sjimharris * operation completed successfully. 181230557Sjimharris */ 182230557Sjimharrisstatic 183230557SjimharrisSCI_STATUS scif_sas_remote_device_ready_operational_stop_handler( 184230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device 185230557Sjimharris) 186230557Sjimharris{ 187230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) 188230557Sjimharris remote_device; 189230557Sjimharris 190230557Sjimharris sci_base_state_machine_change_state( 191230557Sjimharris &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 192230557Sjimharris ); 193230557Sjimharris 194230557Sjimharris return fw_device->operation_status; 195230557Sjimharris} 196230557Sjimharris 197230557Sjimharris/** 198230557Sjimharris * @brief This method provides OPERATIONAL sub-state specific handling for 199230557Sjimharris * when the user attempts to destruct the remote device. In 200230557Sjimharris * the READY state the framework must first stop the device 201230557Sjimharris * before destructing it. 202230557Sjimharris * 203230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 204230557Sjimharris * object for which the framework is attempting to start. 205230557Sjimharris * 206230557Sjimharris * @return This method returns an indication as to whether the destruct 207230557Sjimharris * operation completed successfully. 208230557Sjimharris */ 209230557Sjimharrisstatic 210230557SjimharrisSCI_STATUS scif_sas_remote_device_ready_operational_destruct_handler( 211230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device 212230557Sjimharris) 213230557Sjimharris{ 214230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) 215230557Sjimharris remote_device; 216230557Sjimharris 217230557Sjimharris fw_device->destruct_when_stopped = TRUE; 218230557Sjimharris 219230557Sjimharris return (fw_device->state_handlers->parent.stop_handler(&fw_device->parent)); 220230557Sjimharris} 221230557Sjimharris 222230557Sjimharris/** 223230557Sjimharris * @brief This method provides OPERATIONAL sub-state specific handling for 224230557Sjimharris * when the remote device undergoes a failure condition. 225230557Sjimharris * 226230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 227230557Sjimharris * object for which the failure condition occurred. 228230557Sjimharris * 229230557Sjimharris * @return This method returns an indication as to whether the failure 230230557Sjimharris * operation completed successfully. 231230557Sjimharris */ 232230557Sjimharrisstatic 233230557SjimharrisSCI_STATUS scif_sas_remote_device_ready_operational_fail_handler( 234230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device 235230557Sjimharris) 236230557Sjimharris{ 237230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *) 238230557Sjimharris remote_device; 239230557Sjimharris 240230557Sjimharris SCIF_LOG_WARNING(( 241230557Sjimharris sci_base_object_get_logger(fw_device), 242230557Sjimharris SCIF_LOG_OBJECT_REMOTE_DEVICE, 243230557Sjimharris "RemoteDevice:0x%x ready device failed\n", 244230557Sjimharris fw_device 245230557Sjimharris )); 246230557Sjimharris 247230557Sjimharris sci_base_state_machine_change_state( 248230557Sjimharris &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_FAILED 249230557Sjimharris ); 250230557Sjimharris 251230557Sjimharris /// @todo Fix the return code handling. 252230557Sjimharris return SCI_FAILURE; 253230557Sjimharris} 254230557Sjimharris 255230557Sjimharris/** 256230557Sjimharris * @brief This method provides OPERATIONAL sub-state specific handling for 257230557Sjimharris * when a user attempts to start an IO request on a remote 258230557Sjimharris * device. 259230557Sjimharris * 260230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 261230557Sjimharris * object on which the user is attempting to perform a start 262230557Sjimharris * IO operation. 263230557Sjimharris * @param[in] io_request This parameter specifies the IO request to be 264230557Sjimharris * started. 265230557Sjimharris * 266230557Sjimharris * @return This method returns an indication as to whether the IO request 267230557Sjimharris * started successfully. 268230557Sjimharris */ 269230557Sjimharrisstatic 270230557SjimharrisSCI_STATUS scif_sas_remote_device_ready_operational_start_io_handler( 271230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device, 272230557Sjimharris SCI_BASE_REQUEST_T * io_request 273230557Sjimharris) 274230557Sjimharris{ 275230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 276230557Sjimharris remote_device; 277230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) io_request; 278230557Sjimharris SCI_STATUS status; 279230557Sjimharris 280230557Sjimharris status = fw_io->parent.state_handlers->start_handler(&fw_io->parent.parent); 281230557Sjimharris 282230557Sjimharris if (status == SCI_SUCCESS) 283230557Sjimharris { 284230557Sjimharris fw_device->request_count++; 285230557Sjimharris } 286230557Sjimharris 287230557Sjimharris return status; 288230557Sjimharris} 289230557Sjimharris 290230557Sjimharris/** 291230557Sjimharris * @brief This method provides OPERATIONAL sub-state specific handling for 292230557Sjimharris * when a user attempts to start an IO request on a remote 293230557Sjimharris * device. 294230557Sjimharris * 295230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 296230557Sjimharris * object on which the user is attempting to perform a complete 297230557Sjimharris * IO operation. 298230557Sjimharris * @param[in] io_request This parameter specifies the IO request to 299230557Sjimharris * be completed. 300230557Sjimharris * 301230557Sjimharris * @return This method returns an indication as to whether the IO request 302230557Sjimharris * completed successfully. 303230557Sjimharris */ 304230557SjimharrisSCI_STATUS scif_sas_remote_device_ready_operational_complete_io_handler( 305230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device, 306230557Sjimharris SCI_BASE_REQUEST_T * io_request 307230557Sjimharris) 308230557Sjimharris{ 309230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 310230557Sjimharris remote_device; 311230557Sjimharris fw_device->request_count--; 312230557Sjimharris return SCI_SUCCESS; 313230557Sjimharris} 314230557Sjimharris 315230557Sjimharris 316230557Sjimharris/** 317230557Sjimharris * @brief This method provides OPERATIONAL sub-state specific handling for 318230557Sjimharris * when a user attempts to start an IO request on a remote 319230557Sjimharris * device. 320230557Sjimharris * 321230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 322230557Sjimharris * object on which the user is attempting to perform a complete 323230557Sjimharris * IO operation. 324230557Sjimharris * @param[in] io_request This parameter specifies the IO request to 325230557Sjimharris * be completed. 326230557Sjimharris * 327230557Sjimharris * @return This method returns an indication as to whether the IO request 328230557Sjimharris * completed successfully. 329230557Sjimharris */ 330230557Sjimharrisstatic 331230557SjimharrisSCI_STATUS scif_sas_remote_device_ready_operational_complete_high_priority_io_handler( 332230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device, 333230557Sjimharris SCI_BASE_REQUEST_T * io_request, 334230557Sjimharris void * response_data, 335230557Sjimharris SCI_IO_STATUS completion_status 336230557Sjimharris) 337230557Sjimharris{ 338230557Sjimharris SCIF_LOG_WARNING(( 339230557Sjimharris sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device), 340230557Sjimharris SCIF_LOG_OBJECT_REMOTE_DEVICE, 341230557Sjimharris "RemoteDevice:0x%x State:0x%x invalid state to complete high priority IO\n", 342230557Sjimharris remote_device, 343230557Sjimharris sci_base_state_machine_get_state( 344230557Sjimharris &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine) 345230557Sjimharris )); 346230557Sjimharris 347230557Sjimharris return SCI_FAILURE_INVALID_STATE; 348230557Sjimharris} 349230557Sjimharris 350230557Sjimharris 351230557Sjimharris/** 352230557Sjimharris * @brief This method provides OPERATIONAL sub-state specific handling for when 353230557Sjimharris * the framework attempts to continue an IO request on a remote 354230557Sjimharris * device. 355230557Sjimharris * 356230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 357230557Sjimharris * object on which the user is attempting to perform a continue 358230557Sjimharris * IO operation. 359230557Sjimharris * @param[in] io_request This parameter specifies the IO request to 360230557Sjimharris * be continued. 361230557Sjimharris * 362230557Sjimharris * @return This method returns an indication as to whether the IO request 363230557Sjimharris * completed successfully. 364230557Sjimharris */ 365230557Sjimharrisstatic 366230557SjimharrisSCI_STATUS scif_sas_remote_device_ready_operational_continue_io_handler( 367230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device, 368230557Sjimharris SCI_BASE_REQUEST_T * io_request 369230557Sjimharris) 370230557Sjimharris{ 371230557Sjimharris /// @todo Fix the return code handling. 372230557Sjimharris return SCI_FAILURE; 373230557Sjimharris} 374230557Sjimharris 375230557Sjimharris/** 376230557Sjimharris * @brief This method provides OPERATIONAL sub-state specific handling for 377230557Sjimharris * when a user attempts to start a task management request on 378230557Sjimharris * a remote device. This includes terminating all of the affected 379230557Sjimharris * ongoing IO requests (i.e. aborting them in the silicon) and then 380230557Sjimharris * issuing the task management request to the silicon. 381230557Sjimharris * 382230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 383230557Sjimharris * object on which the user is attempting to perform a start 384230557Sjimharris * task operation. 385230557Sjimharris * @param[in] task_request This parameter specifies the task management 386230557Sjimharris * request to be started. 387230557Sjimharris * 388230557Sjimharris * @return This method returns an indication as to whether the task 389230557Sjimharris * management request started successfully. 390230557Sjimharris */ 391230557Sjimharrisstatic 392230557SjimharrisSCI_STATUS scif_sas_remote_device_ready_operational_start_task_handler( 393230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device, 394230557Sjimharris SCI_BASE_REQUEST_T * task_request 395230557Sjimharris) 396230557Sjimharris{ 397230557Sjimharris SCI_STATUS status = SCI_FAILURE; 398230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 399230557Sjimharris remote_device; 400230557Sjimharris SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*) 401230557Sjimharris task_request; 402230557Sjimharris U8 task_function = 403230557Sjimharris scif_sas_task_request_get_function(fw_task); 404230557Sjimharris 405230557Sjimharris SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; 406230557Sjimharris 407230557Sjimharris scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); 408230557Sjimharris if ( dev_protocols.u.bits.attached_ssp_target 409230557Sjimharris || dev_protocols.u.bits.attached_stp_target) 410230557Sjimharris { 411230557Sjimharris // //NOTE: For STP/SATA targets we currently terminate all requests for 412230557Sjimharris // any type of task management. 413230557Sjimharris if ( (task_function == SCI_SAS_ABORT_TASK_SET) 414230557Sjimharris || (task_function == SCI_SAS_CLEAR_TASK_SET) 415230557Sjimharris || (task_function == SCI_SAS_LOGICAL_UNIT_RESET) 416230557Sjimharris || (task_function == SCI_SAS_I_T_NEXUS_RESET) 417230557Sjimharris || (task_function == SCI_SAS_HARD_RESET) ) 418230557Sjimharris { 419230557Sjimharris // Terminate all of the requests in the silicon for this device. 420230557Sjimharris scif_sas_domain_terminate_requests( 421230557Sjimharris fw_device->domain, fw_device, NULL, fw_task 422230557Sjimharris ); 423230557Sjimharris 424230557Sjimharris status = scif_sas_remote_device_start_task_request(fw_device, fw_task); 425230557Sjimharris } 426230557Sjimharris else if ( (task_function == SCI_SAS_CLEAR_ACA) 427230557Sjimharris || (task_function == SCI_SAS_QUERY_TASK) 428230557Sjimharris || (task_function == SCI_SAS_QUERY_TASK_SET) 429230557Sjimharris || (task_function == SCI_SAS_QUERY_ASYNCHRONOUS_EVENT) ) 430230557Sjimharris { 431230557Sjimharris ASSERT(!dev_protocols.u.bits.attached_stp_target); 432230557Sjimharris status = scif_sas_remote_device_start_task_request(fw_device, fw_task); 433230557Sjimharris } 434230557Sjimharris else if (task_function == SCI_SAS_ABORT_TASK) 435230557Sjimharris { 436230557Sjimharris SCIF_SAS_REQUEST_T * fw_request 437230557Sjimharris = scif_sas_domain_get_request_by_io_tag( 438230557Sjimharris fw_device->domain, fw_task->io_tag_to_manage 439230557Sjimharris ); 440230557Sjimharris 441230557Sjimharris // Determine if the request being aborted was found. 442230557Sjimharris if (fw_request != NULL) 443230557Sjimharris { 444230557Sjimharris scif_sas_domain_terminate_requests( 445230557Sjimharris fw_device->domain, fw_device, fw_request, fw_task 446230557Sjimharris ); 447230557Sjimharris 448230557Sjimharris status = scif_sas_remote_device_start_task_request( 449230557Sjimharris fw_device, fw_task 450230557Sjimharris ); 451230557Sjimharris } 452230557Sjimharris else 453230557Sjimharris status = SCI_FAILURE_INVALID_IO_TAG; 454230557Sjimharris } 455230557Sjimharris } 456230557Sjimharris else 457230557Sjimharris status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; 458230557Sjimharris 459230557Sjimharris if (status != SCI_SUCCESS) 460230557Sjimharris { 461230557Sjimharris SCIF_LOG_ERROR(( 462230557Sjimharris sci_base_object_get_logger(fw_device), 463230557Sjimharris SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 464230557Sjimharris "Controller:0x%x TaskRequest:0x%x Status:0x%x start task failure\n", 465230557Sjimharris fw_device, fw_task, status 466230557Sjimharris )); 467230557Sjimharris } 468230557Sjimharris 469230557Sjimharris return status; 470230557Sjimharris} 471230557Sjimharris 472230557Sjimharris/** 473230557Sjimharris * @brief This method provides OPERATIONAL sub-state specific handling for 474230557Sjimharris * when a user attempts to complete a task management request on 475230557Sjimharris * a remote device. 476230557Sjimharris * 477230557Sjimharris * @param[in] remote_device This parameter specifies the remote device object 478230557Sjimharris * on which the user is attempting to perform a complete task 479230557Sjimharris * operation. 480230557Sjimharris * @param[in] task_request This parameter specifies the task management 481230557Sjimharris * request to be completed. 482230557Sjimharris * 483230557Sjimharris * @return This method returns an indication as to whether the task 484230557Sjimharris * management request succeeded. 485230557Sjimharris */ 486230557SjimharrisSCI_STATUS scif_sas_remote_device_ready_operational_complete_task_handler( 487230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device, 488230557Sjimharris SCI_BASE_REQUEST_T * task_request 489230557Sjimharris) 490230557Sjimharris{ 491230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 492230557Sjimharris remote_device; 493230557Sjimharris fw_device->request_count--; 494230557Sjimharris fw_device->task_request_count--; 495230557Sjimharris 496230557Sjimharris return SCI_SUCCESS; 497230557Sjimharris} 498230557Sjimharris 499230557Sjimharris/** 500230557Sjimharris * @brief This method provides OPERATIONAL sub-state specific handling for 501230557Sjimharris * when a user attempts to start a high priority IO request on a remote 502230557Sjimharris * device. 503230557Sjimharris * 504230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 505230557Sjimharris * object on which the user is attempting to perform a start 506230557Sjimharris * IO operation. 507230557Sjimharris * @param[in] io_request This parameter specifies the IO request to be 508230557Sjimharris * started. 509230557Sjimharris * 510230557Sjimharris * @return This method returns an indication as to whether the IO request 511230557Sjimharris * started successfully. 512230557Sjimharris */ 513230557Sjimharrisstatic 514230557SjimharrisSCI_STATUS scif_sas_remote_device_ready_operational_start_high_priority_io_handler( 515230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device, 516230557Sjimharris SCI_BASE_REQUEST_T * io_request 517230557Sjimharris) 518230557Sjimharris{ 519230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 520230557Sjimharris remote_device; 521230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) io_request; 522230557Sjimharris 523230557Sjimharris SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; 524230557Sjimharris 525230557Sjimharris scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); 526230557Sjimharris 527230557Sjimharris if (dev_protocols.u.bits.attached_smp_target) 528230557Sjimharris { 529230557Sjimharris //transit to task management state for smp request phase. 530230557Sjimharris if (fw_device->ready_substate_machine.current_state_id 531230557Sjimharris != SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT) 532230557Sjimharris { 533230557Sjimharris sci_base_state_machine_change_state( 534230557Sjimharris &fw_device->ready_substate_machine, 535230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT 536230557Sjimharris ); 537230557Sjimharris } 538230557Sjimharris } 539230557Sjimharris 540230557Sjimharris fw_device->request_count++; 541230557Sjimharris 542230557Sjimharris return fw_io->parent.state_handlers->start_handler(&fw_io->parent.parent); 543230557Sjimharris} 544230557Sjimharris 545230557Sjimharris 546230557Sjimharris/** 547230557Sjimharris * @brief This method provides TASK MANAGEMENT sub-state specific handling for 548230557Sjimharris * when a user attempts to complete a task management request on 549230557Sjimharris * a remote device. 550230557Sjimharris * 551230557Sjimharris * @param[in] remote_device This parameter specifies the remote device object 552230557Sjimharris * on which the user is attempting to perform a complete task 553230557Sjimharris * operation. 554230557Sjimharris * @param[in] task_request This parameter specifies the task management 555230557Sjimharris * request to be completed. 556230557Sjimharris * 557230557Sjimharris * @return This method returns an indication as to whether the task 558230557Sjimharris * management request succeeded. 559230557Sjimharris */ 560230557SjimharrisSCI_STATUS scif_sas_remote_device_ready_task_management_complete_task_handler( 561230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device, 562230557Sjimharris SCI_BASE_REQUEST_T * task_request 563230557Sjimharris) 564230557Sjimharris{ 565230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 566230557Sjimharris remote_device; 567230557Sjimharris 568230557Sjimharris SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T *) 569230557Sjimharris task_request; 570230557Sjimharris 571230557Sjimharris fw_device->request_count--; 572230557Sjimharris fw_device->task_request_count--; 573230557Sjimharris 574230557Sjimharris // All existing task management requests and all of the IO requests 575230557Sjimharris // affectected by the task management request must complete before 576230557Sjimharris // the remote device can transition back into the READY / OPERATIONAL 577230557Sjimharris // state. 578230557Sjimharris if ( (fw_device->task_request_count == 0) 579230557Sjimharris && (fw_task->affected_request_count == 0) ) 580230557Sjimharris { 581230557Sjimharris sci_base_state_machine_change_state( 582230557Sjimharris &fw_device->ready_substate_machine, 583230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL 584230557Sjimharris ); 585230557Sjimharris } 586230557Sjimharris 587230557Sjimharris return SCI_SUCCESS; 588230557Sjimharris} 589230557Sjimharris 590230557Sjimharris/** 591230557Sjimharris * @brief This method provides SUSPENDED sub-state specific handling for 592230557Sjimharris * when the core remote device object issues a device ready 593230557Sjimharris * notification. This effectively causes the framework remote 594230557Sjimharris * device to transition back into the OPERATIONAL state. 595230557Sjimharris * 596230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 597230557Sjimharris * object for which the notification occurred. 598230557Sjimharris * 599230557Sjimharris * @return none. 600230557Sjimharris */ 601230557Sjimharrisstatic 602230557Sjimharrisvoid scif_sas_remote_device_ready_suspended_ready_handler( 603230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device 604230557Sjimharris) 605230557Sjimharris{ 606230557Sjimharris sci_base_state_machine_change_state( 607230557Sjimharris &fw_device->ready_substate_machine, 608230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL 609230557Sjimharris ); 610230557Sjimharris} 611230557Sjimharris 612230557Sjimharris 613230557Sjimharris/** 614230557Sjimharris * @brief This handler is currently solely used by smp remote device for 615230557Sjimharris * discovering. 616230557Sjimharris * 617230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 618230557Sjimharris * object on which the user is attempting to perform a complete high 619230557Sjimharris * priority IO operation. 620230557Sjimharris * @param[in] io_request This parameter specifies the high priority IO request 621230557Sjimharris * to be completed. 622230557Sjimharris * 623230557Sjimharris * @return SCI_STATUS indicate whether the io complete successfully. 624230557Sjimharris */ 625230557SjimharrisSCI_STATUS 626230557Sjimharrisscif_sas_remote_device_ready_task_management_complete_high_priority_io_handler( 627230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * remote_device, 628230557Sjimharris SCI_BASE_REQUEST_T * io_request, 629230557Sjimharris void * response_data, 630230557Sjimharris SCI_IO_STATUS completion_status 631230557Sjimharris) 632230557Sjimharris{ 633230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 634230557Sjimharris remote_device; 635230557Sjimharris SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) io_request; 636230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 637230557Sjimharris SCIC_TRANSPORT_PROTOCOL protocol; 638230557Sjimharris 639230557Sjimharris SCIF_LOG_TRACE(( 640230557Sjimharris sci_base_object_get_logger(remote_device), 641230557Sjimharris SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_IO_REQUEST, 642230557Sjimharris "scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 643230557Sjimharris remote_device, io_request, response_data, completion_status 644230557Sjimharris )); 645230557Sjimharris 646230557Sjimharris fw_device->request_count--; 647230557Sjimharris 648230557Sjimharris // we are back to ready operational sub state here. 649230557Sjimharris sci_base_state_machine_change_state( 650230557Sjimharris &fw_device->ready_substate_machine, 651230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL 652230557Sjimharris ); 653230557Sjimharris 654230557Sjimharris protocol = scic_io_request_get_protocol(fw_request->core_object); 655230557Sjimharris 656230557Sjimharris // If this request was an SMP initiator request we created, then 657230557Sjimharris // decode the response. 658230557Sjimharris if (protocol == SCIC_SMP_PROTOCOL) 659230557Sjimharris { 660230557Sjimharris if (completion_status != SCI_IO_FAILURE_TERMINATED) 661230557Sjimharris { 662230557Sjimharris status = scif_sas_smp_remote_device_decode_smp_response( 663230557Sjimharris fw_device, fw_request, response_data, completion_status 664230557Sjimharris ); 665230557Sjimharris } 666230557Sjimharris else 667230557Sjimharris scif_sas_smp_remote_device_terminated_request_handler(fw_device, fw_request); 668230557Sjimharris } 669230557Sjimharris else 670230557Sjimharris { 671230557Sjimharris // Currently, there are only internal SMP requests. So, default work 672230557Sjimharris // is simply to clean up the internal request. 673230557Sjimharris if (fw_request->is_internal == TRUE) 674230557Sjimharris { 675230557Sjimharris scif_sas_internal_io_request_complete( 676230557Sjimharris fw_device->domain->controller, 677230557Sjimharris (SCIF_SAS_INTERNAL_IO_REQUEST_T *)fw_request, 678230557Sjimharris SCI_SUCCESS 679230557Sjimharris ); 680230557Sjimharris } 681230557Sjimharris } 682230557Sjimharris 683230557Sjimharris return status; 684230557Sjimharris} 685230557Sjimharris 686230557Sjimharris 687230557SjimharrisSCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T 688230557Sjimharrisscif_sas_remote_device_ready_substate_handler_table[] = 689230557Sjimharris{ 690230557Sjimharris // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL 691230557Sjimharris { 692230557Sjimharris { 693230557Sjimharris scif_sas_remote_device_default_start_handler, 694230557Sjimharris scif_sas_remote_device_ready_operational_stop_handler, 695230557Sjimharris scif_sas_remote_device_ready_operational_fail_handler, 696230557Sjimharris scif_sas_remote_device_ready_operational_destruct_handler, 697230557Sjimharris scif_sas_remote_device_default_reset_handler, 698230557Sjimharris scif_sas_remote_device_default_reset_complete_handler, 699230557Sjimharris scif_sas_remote_device_ready_operational_start_io_handler, 700230557Sjimharris scif_sas_remote_device_ready_operational_complete_io_handler, 701230557Sjimharris scif_sas_remote_device_ready_operational_continue_io_handler, 702230557Sjimharris scif_sas_remote_device_ready_operational_start_task_handler, 703230557Sjimharris scif_sas_remote_device_ready_operational_complete_task_handler 704230557Sjimharris }, 705230557Sjimharris scif_sas_remote_device_default_start_complete_handler, 706230557Sjimharris scif_sas_remote_device_default_stop_complete_handler, 707230557Sjimharris scif_sas_remote_device_default_ready_handler, 708230557Sjimharris scif_sas_remote_device_ready_operational_not_ready_handler, 709230557Sjimharris scif_sas_remote_device_ready_operational_start_high_priority_io_handler, // 710230557Sjimharris scif_sas_remote_device_ready_operational_complete_high_priority_io_handler 711230557Sjimharris }, 712230557Sjimharris // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED 713230557Sjimharris { 714230557Sjimharris { 715230557Sjimharris scif_sas_remote_device_default_start_handler, 716230557Sjimharris scif_sas_remote_device_ready_operational_stop_handler, 717230557Sjimharris scif_sas_remote_device_ready_operational_fail_handler, 718230557Sjimharris scif_sas_remote_device_ready_operational_destruct_handler, 719230557Sjimharris scif_sas_remote_device_default_reset_handler, 720230557Sjimharris scif_sas_remote_device_default_reset_complete_handler, 721230557Sjimharris scif_sas_remote_device_default_start_io_handler, 722230557Sjimharris scif_sas_remote_device_ready_operational_complete_io_handler, 723230557Sjimharris scif_sas_remote_device_default_continue_io_handler, 724230557Sjimharris scif_sas_remote_device_ready_operational_start_task_handler, 725230557Sjimharris scif_sas_remote_device_ready_operational_complete_task_handler 726230557Sjimharris }, 727230557Sjimharris scif_sas_remote_device_default_start_complete_handler, 728230557Sjimharris scif_sas_remote_device_default_stop_complete_handler, 729230557Sjimharris scif_sas_remote_device_ready_suspended_ready_handler, 730230557Sjimharris scif_sas_remote_device_default_not_ready_handler, 731230557Sjimharris scif_sas_remote_device_default_start_io_handler, 732230557Sjimharris scif_sas_remote_device_ready_operational_complete_high_priority_io_handler 733230557Sjimharris }, 734230557Sjimharris // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT 735230557Sjimharris { 736230557Sjimharris { 737230557Sjimharris scif_sas_remote_device_default_start_handler, 738230557Sjimharris scif_sas_remote_device_ready_operational_stop_handler, 739230557Sjimharris scif_sas_remote_device_ready_operational_fail_handler, 740230557Sjimharris scif_sas_remote_device_ready_operational_destruct_handler, 741230557Sjimharris scif_sas_remote_device_default_reset_handler, 742230557Sjimharris scif_sas_remote_device_default_reset_complete_handler, 743230557Sjimharris scif_sas_remote_device_default_start_io_handler, 744230557Sjimharris scif_sas_remote_device_ready_operational_complete_io_handler, 745230557Sjimharris scif_sas_remote_device_ready_operational_continue_io_handler, 746230557Sjimharris scif_sas_remote_device_ready_operational_start_task_handler, 747230557Sjimharris scif_sas_remote_device_ready_task_management_complete_task_handler 748230557Sjimharris }, 749230557Sjimharris scif_sas_remote_device_default_start_complete_handler, 750230557Sjimharris scif_sas_remote_device_default_stop_complete_handler, 751230557Sjimharris scif_sas_remote_device_default_ready_handler, 752230557Sjimharris scif_sas_remote_device_ready_task_management_not_ready_handler, 753230557Sjimharris scif_sas_remote_device_ready_operational_start_high_priority_io_handler, 754230557Sjimharris scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler 755230557Sjimharris }, 756230557Sjimharris // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 757230557Sjimharris { 758230557Sjimharris { 759230557Sjimharris scif_sas_remote_device_default_start_handler, 760230557Sjimharris scif_sas_remote_device_ready_operational_stop_handler, 761230557Sjimharris scif_sas_remote_device_ready_operational_fail_handler, 762230557Sjimharris scif_sas_remote_device_ready_operational_destruct_handler, 763230557Sjimharris scif_sas_remote_device_default_reset_handler, 764230557Sjimharris scif_sas_remote_device_default_reset_complete_handler, 765230557Sjimharris scif_sas_remote_device_default_start_io_handler, 766230557Sjimharris scif_sas_remote_device_ready_operational_complete_io_handler, 767230557Sjimharris scif_sas_remote_device_default_continue_io_handler, 768230557Sjimharris scif_sas_remote_device_ready_operational_start_task_handler, 769230557Sjimharris scif_sas_remote_device_ready_operational_complete_task_handler 770230557Sjimharris }, 771230557Sjimharris scif_sas_remote_device_default_start_complete_handler, 772230557Sjimharris scif_sas_remote_device_default_stop_complete_handler, 773230557Sjimharris scif_sas_remote_device_ready_suspended_ready_handler, 774230557Sjimharris scif_sas_remote_device_default_not_ready_handler, 775230557Sjimharris scif_sas_remote_device_default_start_io_handler, 776230557Sjimharris scif_sas_remote_device_ready_operational_complete_high_priority_io_handler 777230557Sjimharris }, 778230557Sjimharris}; 779230557Sjimharris 780