1/*- 2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0 3 * 4 * This file is provided under a dual BSD/GPLv2 license. When using or 5 * redistributing this file, you may do so under either license. 6 * 7 * GPL LICENSE SUMMARY 8 * 9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of version 2 of the GNU General Public License as 13 * published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 23 * The full GNU General Public License is included in this distribution 24 * in the file called LICENSE.GPL. 25 * 26 * BSD LICENSE 27 * 28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 34 * 35 * * Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * * Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in 39 * the documentation and/or other materials provided with the 40 * distribution. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 */ 54 55#include <sys/cdefs.h> 56__FBSDID("$FreeBSD$"); 57 58/** 59 * @file 60 * 61 * @brief This file contains the entrance and exit methods for the ready 62 * sub-state machine states (OPERATIONAL, TASK_MGMT). 63 */ 64 65#include <dev/isci/scil/scif_sas_remote_device.h> 66#include <dev/isci/scil/scif_sas_domain.h> 67#include <dev/isci/scil/scif_sas_logger.h> 68#include <dev/isci/scil/scif_sas_internal_io_request.h> 69#include <dev/isci/scil/scif_sas_controller.h> 70#include <dev/isci/scil/sci_controller.h> 71 72//****************************************************************************** 73//* P R O T E C T E D M E T H O D S 74//****************************************************************************** 75 76/** 77 * @brief This method implements the actions taken when entering the 78 * READY OPERATIONAL substate. This includes setting the state 79 * handler methods and issuing a scif_cb_remote_device_ready() 80 * notification to the user. 81 * 82 * @param[in] object This parameter specifies the base object for which 83 * the state transition is occurring. This is cast into a 84 * SCIF_SAS_REMOTE_DEVICE object in the method implementation. 85 * 86 * @return none 87 */ 88static 89void scif_sas_remote_device_ready_operational_substate_enter( 90 SCI_BASE_OBJECT_T *object 91) 92{ 93 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object; 94 95 SET_STATE_HANDLER( 96 fw_device, 97 scif_sas_remote_device_ready_substate_handler_table, 98 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL 99 ); 100 101 SCIF_LOG_INFO(( 102 sci_base_object_get_logger(fw_device), 103 SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG, 104 "Domain:0x%x Device:0x%x device ready\n", 105 fw_device->domain, fw_device 106 )); 107 108 // Notify the user that the device has become ready. 109 scif_cb_remote_device_ready( 110 fw_device->domain->controller, fw_device->domain, fw_device 111 ); 112} 113 114/** 115 * @brief This method implements the actions taken when exiting the 116 * READY OPERATIONAL substate. This method issues a 117 * scif_cb_remote_device_not_ready() notification to the framework 118 * user. 119 * 120 * @param[in] object This parameter specifies the base object for which 121 * the state transition is occurring. This is cast into a 122 * SCIF_SAS_REMOTE_DEVICE object in the method implementation. 123 * 124 * @return none 125 */ 126static 127void scif_sas_remote_device_ready_operational_substate_exit( 128 SCI_BASE_OBJECT_T *object 129) 130{ 131 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object; 132 133 // Notify the user that the device has become ready. 134 scif_cb_remote_device_not_ready( 135 fw_device->domain->controller, fw_device->domain, fw_device 136 ); 137} 138 139/** 140 * @brief This method implements the actions taken when entering the 141 * READY SUSPENDED substate. This includes setting the state 142 * handler methods. 143 * 144 * @param[in] object This parameter specifies the base object for which 145 * the state transition is occurring. This is cast into a 146 * SCIF_SAS_REMOTE_DEVICE object in the method implementation. 147 * 148 * @return none 149 */ 150static 151void scif_sas_remote_device_ready_suspended_substate_enter( 152 SCI_BASE_OBJECT_T *object 153) 154{ 155 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object; 156 157 SET_STATE_HANDLER( 158 fw_device, 159 scif_sas_remote_device_ready_substate_handler_table, 160 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED 161 ); 162} 163 164/** 165 * @brief This method implements the actions taken when entering the 166 * READY TASK MGMT substate. This includes setting the state 167 * handler methods. 168 * 169 * @param[in] object This parameter specifies the base object for which 170 * the state transition is occurring. This is cast into a 171 * SCIF_SAS_REMOTE_DEVICE object in the method implementation. 172 * 173 * @return none 174 */ 175static 176void scif_sas_remote_device_ready_taskmgmt_substate_enter( 177 SCI_BASE_OBJECT_T *object 178) 179{ 180 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object; 181 182 SET_STATE_HANDLER( 183 fw_device, 184 scif_sas_remote_device_ready_substate_handler_table, 185 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT 186 ); 187} 188 189/** 190* @brief This method implements the actions taken when entering the 191* READY NCQ ERROR substate. This includes setting the state 192* handler methods. 193* 194* @param[in] object This parameter specifies the base object for which 195* the state transition is occurring. This is cast into a 196* SCIF_SAS_REMOTE_DEVICE object in the method implementation. 197* 198* @return none 199*/ 200static 201void scif_sas_remote_device_ready_ncq_error_substate_enter( 202 SCI_BASE_OBJECT_T *object 203) 204{ 205 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object; 206 SCI_STATUS status = SCI_SUCCESS; 207 SCI_TASK_REQUEST_HANDLE_T handle; 208 SCIF_SAS_CONTROLLER_T * fw_controller = fw_device->domain->controller; 209 SCIF_SAS_TASK_REQUEST_T * fw_task_request; 210 SCIF_SAS_REQUEST_T * fw_request; 211 void * internal_task_memory; 212 SCIF_SAS_DOMAIN_T * fw_domain = fw_device->domain; 213 SCI_FAST_LIST_ELEMENT_T * pending_request_element; 214 SCIF_SAS_REQUEST_T * pending_request = NULL; 215 216 SET_STATE_HANDLER( 217 fw_device, 218 scif_sas_remote_device_ready_substate_handler_table, 219 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR 220 ); 221 222 internal_task_memory = scif_sas_controller_allocate_internal_request(fw_controller); 223 ASSERT(internal_task_memory != NULL); 224 225 fw_task_request = (SCIF_SAS_TASK_REQUEST_T*)internal_task_memory; 226 227 fw_request = &fw_task_request->parent; 228 229 //construct the scif io request 230 status = scif_sas_internal_task_request_construct( 231 fw_controller, 232 fw_device, 233 SCI_CONTROLLER_INVALID_IO_TAG, 234 (void *)fw_task_request, 235 &handle, 236 SCI_SAS_ABORT_TASK_SET 237 ); 238 239 pending_request_element = fw_domain->request_list.list_head; 240 241 // Cycle through the fast list of IO requests. Mark each request 242 // pending to this remote device so that they are not completed 243 // to the operating system when the request is terminated, but 244 // rather when the abort task set completes. 245 while (pending_request_element != NULL) 246 { 247 pending_request = 248 (SCIF_SAS_REQUEST_T*) sci_fast_list_get_object(pending_request_element); 249 250 // The current element may be deleted from the list because of 251 // IO completion so advance to the next element early 252 pending_request_element = sci_fast_list_get_next(pending_request_element); 253 254 if (pending_request->device == fw_device) 255 { 256 pending_request->is_waiting_for_abort_task_set = TRUE; 257 } 258 } 259 260 scif_controller_start_task( 261 fw_controller, 262 fw_device, 263 fw_request, 264 SCI_CONTROLLER_INVALID_IO_TAG 265 ); 266} 267 268SCI_BASE_STATE_T scif_sas_remote_device_ready_substate_table 269[SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_MAX_STATES] = 270{ 271 { 272 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL, 273 scif_sas_remote_device_ready_operational_substate_enter, 274 scif_sas_remote_device_ready_operational_substate_exit 275 }, 276 { 277 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED, 278 scif_sas_remote_device_ready_suspended_substate_enter, 279 NULL 280 }, 281 { 282 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT, 283 scif_sas_remote_device_ready_taskmgmt_substate_enter, 284 NULL 285 }, 286 { 287 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR, 288 scif_sas_remote_device_ready_ncq_error_substate_enter, 289 NULL 290 } 291}; 292 293