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 the entrance and exit methods for the ready 60230557Sjimharris * sub-state machine states (OPERATIONAL, TASK_MGMT). 61230557Sjimharris */ 62230557Sjimharris 63230557Sjimharris#include <dev/isci/scil/scif_sas_remote_device.h> 64230557Sjimharris#include <dev/isci/scil/scif_sas_domain.h> 65230557Sjimharris#include <dev/isci/scil/scif_sas_logger.h> 66230557Sjimharris#include <dev/isci/scil/scif_sas_internal_io_request.h> 67230557Sjimharris#include <dev/isci/scil/scif_sas_controller.h> 68230557Sjimharris#include <dev/isci/scil/sci_controller.h> 69230557Sjimharris 70230557Sjimharris//****************************************************************************** 71230557Sjimharris//* P R O T E C T E D M E T H O D S 72230557Sjimharris//****************************************************************************** 73230557Sjimharris 74230557Sjimharris/** 75230557Sjimharris * @brief This method implements the actions taken when entering the 76230557Sjimharris * READY OPERATIONAL substate. This includes setting the state 77230557Sjimharris * handler methods and issuing a scif_cb_remote_device_ready() 78230557Sjimharris * notification to the user. 79230557Sjimharris * 80230557Sjimharris * @param[in] object This parameter specifies the base object for which 81230557Sjimharris * the state transition is occurring. This is cast into a 82230557Sjimharris * SCIF_SAS_REMOTE_DEVICE object in the method implementation. 83230557Sjimharris * 84230557Sjimharris * @return none 85230557Sjimharris */ 86230557Sjimharrisstatic 87230557Sjimharrisvoid scif_sas_remote_device_ready_operational_substate_enter( 88230557Sjimharris SCI_BASE_OBJECT_T *object 89230557Sjimharris) 90230557Sjimharris{ 91230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object; 92230557Sjimharris 93230557Sjimharris SET_STATE_HANDLER( 94230557Sjimharris fw_device, 95230557Sjimharris scif_sas_remote_device_ready_substate_handler_table, 96230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL 97230557Sjimharris ); 98230557Sjimharris 99230557Sjimharris SCIF_LOG_INFO(( 100230557Sjimharris sci_base_object_get_logger(fw_device), 101230557Sjimharris SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG, 102230557Sjimharris "Domain:0x%x Device:0x%x device ready\n", 103230557Sjimharris fw_device->domain, fw_device 104230557Sjimharris )); 105230557Sjimharris 106230557Sjimharris // Notify the user that the device has become ready. 107230557Sjimharris scif_cb_remote_device_ready( 108230557Sjimharris fw_device->domain->controller, fw_device->domain, fw_device 109230557Sjimharris ); 110230557Sjimharris} 111230557Sjimharris 112230557Sjimharris/** 113230557Sjimharris * @brief This method implements the actions taken when exiting the 114230557Sjimharris * READY OPERATIONAL substate. This method issues a 115230557Sjimharris * scif_cb_remote_device_not_ready() notification to the framework 116230557Sjimharris * user. 117230557Sjimharris * 118230557Sjimharris * @param[in] object This parameter specifies the base object for which 119230557Sjimharris * the state transition is occurring. This is cast into a 120230557Sjimharris * SCIF_SAS_REMOTE_DEVICE object in the method implementation. 121230557Sjimharris * 122230557Sjimharris * @return none 123230557Sjimharris */ 124230557Sjimharrisstatic 125230557Sjimharrisvoid scif_sas_remote_device_ready_operational_substate_exit( 126230557Sjimharris SCI_BASE_OBJECT_T *object 127230557Sjimharris) 128230557Sjimharris{ 129230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object; 130230557Sjimharris 131230557Sjimharris // Notify the user that the device has become ready. 132230557Sjimharris scif_cb_remote_device_not_ready( 133230557Sjimharris fw_device->domain->controller, fw_device->domain, fw_device 134230557Sjimharris ); 135230557Sjimharris} 136230557Sjimharris 137230557Sjimharris/** 138230557Sjimharris * @brief This method implements the actions taken when entering the 139230557Sjimharris * READY SUSPENDED substate. This includes setting the state 140230557Sjimharris * handler methods. 141230557Sjimharris * 142230557Sjimharris * @param[in] object This parameter specifies the base object for which 143230557Sjimharris * the state transition is occurring. This is cast into a 144230557Sjimharris * SCIF_SAS_REMOTE_DEVICE object in the method implementation. 145230557Sjimharris * 146230557Sjimharris * @return none 147230557Sjimharris */ 148230557Sjimharrisstatic 149230557Sjimharrisvoid scif_sas_remote_device_ready_suspended_substate_enter( 150230557Sjimharris SCI_BASE_OBJECT_T *object 151230557Sjimharris) 152230557Sjimharris{ 153230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object; 154230557Sjimharris 155230557Sjimharris SET_STATE_HANDLER( 156230557Sjimharris fw_device, 157230557Sjimharris scif_sas_remote_device_ready_substate_handler_table, 158230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED 159230557Sjimharris ); 160230557Sjimharris} 161230557Sjimharris 162230557Sjimharris/** 163230557Sjimharris * @brief This method implements the actions taken when entering the 164230557Sjimharris * READY TASK MGMT substate. This includes setting the state 165230557Sjimharris * handler methods. 166230557Sjimharris * 167230557Sjimharris * @param[in] object This parameter specifies the base object for which 168230557Sjimharris * the state transition is occurring. This is cast into a 169230557Sjimharris * SCIF_SAS_REMOTE_DEVICE object in the method implementation. 170230557Sjimharris * 171230557Sjimharris * @return none 172230557Sjimharris */ 173230557Sjimharrisstatic 174230557Sjimharrisvoid scif_sas_remote_device_ready_taskmgmt_substate_enter( 175230557Sjimharris SCI_BASE_OBJECT_T *object 176230557Sjimharris) 177230557Sjimharris{ 178230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object; 179230557Sjimharris 180230557Sjimharris SET_STATE_HANDLER( 181230557Sjimharris fw_device, 182230557Sjimharris scif_sas_remote_device_ready_substate_handler_table, 183230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT 184230557Sjimharris ); 185230557Sjimharris} 186230557Sjimharris 187230557Sjimharris/** 188230557Sjimharris* @brief This method implements the actions taken when entering the 189230557Sjimharris* READY NCQ ERROR substate. This includes setting the state 190230557Sjimharris* handler methods. 191230557Sjimharris* 192230557Sjimharris* @param[in] object This parameter specifies the base object for which 193230557Sjimharris* the state transition is occurring. This is cast into a 194230557Sjimharris* SCIF_SAS_REMOTE_DEVICE object in the method implementation. 195230557Sjimharris* 196230557Sjimharris* @return none 197230557Sjimharris*/ 198230557Sjimharrisstatic 199230557Sjimharrisvoid scif_sas_remote_device_ready_ncq_error_substate_enter( 200230557Sjimharris SCI_BASE_OBJECT_T *object 201230557Sjimharris) 202230557Sjimharris{ 203230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object; 204230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 205230557Sjimharris SCI_TASK_REQUEST_HANDLE_T handle; 206230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = fw_device->domain->controller; 207230557Sjimharris SCIF_SAS_TASK_REQUEST_T * fw_task_request; 208230557Sjimharris SCIF_SAS_REQUEST_T * fw_request; 209230557Sjimharris void * internal_task_memory; 210230557Sjimharris SCIF_SAS_DOMAIN_T * fw_domain = fw_device->domain; 211230557Sjimharris SCI_FAST_LIST_ELEMENT_T * pending_request_element; 212230557Sjimharris SCIF_SAS_REQUEST_T * pending_request = NULL; 213230557Sjimharris 214230557Sjimharris SET_STATE_HANDLER( 215230557Sjimharris fw_device, 216230557Sjimharris scif_sas_remote_device_ready_substate_handler_table, 217230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 218230557Sjimharris ); 219230557Sjimharris 220230557Sjimharris internal_task_memory = scif_sas_controller_allocate_internal_request(fw_controller); 221230557Sjimharris ASSERT(internal_task_memory != NULL); 222230557Sjimharris 223230557Sjimharris fw_task_request = (SCIF_SAS_TASK_REQUEST_T*)internal_task_memory; 224230557Sjimharris 225230557Sjimharris fw_request = &fw_task_request->parent; 226230557Sjimharris 227230557Sjimharris //construct the scif io request 228230557Sjimharris status = scif_sas_internal_task_request_construct( 229230557Sjimharris fw_controller, 230230557Sjimharris fw_device, 231230557Sjimharris SCI_CONTROLLER_INVALID_IO_TAG, 232230557Sjimharris (void *)fw_task_request, 233230557Sjimharris &handle, 234230557Sjimharris SCI_SAS_ABORT_TASK_SET 235230557Sjimharris ); 236230557Sjimharris 237230557Sjimharris pending_request_element = fw_domain->request_list.list_head; 238230557Sjimharris 239230557Sjimharris // Cycle through the fast list of IO requests. Mark each request 240230557Sjimharris // pending to this remote device so that they are not completed 241230557Sjimharris // to the operating system when the request is terminated, but 242230557Sjimharris // rather when the abort task set completes. 243230557Sjimharris while (pending_request_element != NULL) 244230557Sjimharris { 245230557Sjimharris pending_request = 246230557Sjimharris (SCIF_SAS_REQUEST_T*) sci_fast_list_get_object(pending_request_element); 247230557Sjimharris 248230557Sjimharris // The current element may be deleted from the list becasue of 249230557Sjimharris // IO completion so advance to the next element early 250230557Sjimharris pending_request_element = sci_fast_list_get_next(pending_request_element); 251230557Sjimharris 252230557Sjimharris if (pending_request->device == fw_device) 253230557Sjimharris { 254230557Sjimharris pending_request->is_waiting_for_abort_task_set = TRUE; 255230557Sjimharris } 256230557Sjimharris } 257230557Sjimharris 258231296Sjimharris scif_controller_start_task( 259230557Sjimharris fw_controller, 260230557Sjimharris fw_device, 261230557Sjimharris fw_request, 262230557Sjimharris SCI_CONTROLLER_INVALID_IO_TAG 263230557Sjimharris ); 264230557Sjimharris} 265230557Sjimharris 266230557SjimharrisSCI_BASE_STATE_T scif_sas_remote_device_ready_substate_table 267230557Sjimharris[SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_MAX_STATES] = 268230557Sjimharris{ 269230557Sjimharris { 270230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL, 271230557Sjimharris scif_sas_remote_device_ready_operational_substate_enter, 272230557Sjimharris scif_sas_remote_device_ready_operational_substate_exit 273230557Sjimharris }, 274230557Sjimharris { 275230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED, 276230557Sjimharris scif_sas_remote_device_ready_suspended_substate_enter, 277230557Sjimharris NULL 278230557Sjimharris }, 279230557Sjimharris { 280230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT, 281230557Sjimharris scif_sas_remote_device_ready_taskmgmt_substate_enter, 282230557Sjimharris NULL 283230557Sjimharris }, 284230557Sjimharris { 285230557Sjimharris SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR, 286230557Sjimharris scif_sas_remote_device_ready_ncq_error_substate_enter, 287230557Sjimharris NULL 288230557Sjimharris } 289230557Sjimharris}; 290230557Sjimharris 291