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 all of the entrance and exit methods for each 62 * of the controller states defined by the SCI_BASE_CONTROLLER state 63 * machine. 64 */ 65 66 #include <dev/isci/scil/scic_controller.h> 67 68 #include <dev/isci/scil/scif_sas_logger.h> 69 #include <dev/isci/scil/scif_sas_controller.h> 70 71 //****************************************************************************** 72 //* P R O T E C T E D M E T H O D S 73 //****************************************************************************** 74 75 /** 76 * @brief This method implements the actions taken when entering the 77 * INITIAL state. 78 * 79 * @param[in] object This parameter specifies the base object for which 80 * the state transition is occurring. This is cast into a 81 * SCIF_SAS_CONTROLLER object in the method implementation. 82 * 83 * @return none 84 */ 85 static 86 void scif_sas_controller_initial_state_enter( 87 SCI_BASE_OBJECT_T * object 88 ) 89 { 90 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 91 92 SET_STATE_HANDLER( 93 fw_controller, 94 scif_sas_controller_state_handler_table, 95 SCI_BASE_CONTROLLER_STATE_INITIAL 96 ); 97 } 98 99 /** 100 * @brief This method implements the actions taken when entering the 101 * RESET state. 102 * 103 * @param[in] object This parameter specifies the base object for which 104 * the state transition is occurring. This is cast into a 105 * SCIF_SAS_CONTROLLER object in the method implementation. 106 * 107 * @return none 108 */ 109 static 110 void scif_sas_controller_reset_state_enter( 111 SCI_BASE_OBJECT_T * object 112 ) 113 { 114 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 115 U8 index; 116 U16 smp_phy_index; 117 118 SET_STATE_HANDLER( 119 fw_controller, 120 scif_sas_controller_state_handler_table, 121 SCI_BASE_CONTROLLER_STATE_RESET 122 ); 123 124 scif_sas_high_priority_request_queue_construct( 125 &fw_controller->hprq, sci_base_object_get_logger(fw_controller) 126 ); 127 128 // Construct the abstract element pool. This pool will store the 129 // references to the framework's remote devices objects. 130 sci_abstract_element_pool_construct( 131 &fw_controller->free_remote_device_pool, 132 fw_controller->remote_device_pool_elements, 133 SCI_MAX_REMOTE_DEVICES 134 ); 135 136 // Construct the domain objects. 137 for (index = 0; index < SCI_MAX_DOMAINS; index++) 138 { 139 scif_sas_domain_construct( 140 &fw_controller->domains[index], index, fw_controller 141 ); 142 } 143 144 //Initialize SMP PHY MEMORY LIST. 145 sci_fast_list_init(&fw_controller->smp_phy_memory_list); 146 147 for (smp_phy_index = 0; 148 smp_phy_index < SCIF_SAS_SMP_PHY_COUNT; 149 smp_phy_index++) 150 { 151 sci_fast_list_element_init( 152 &fw_controller->smp_phy_array[smp_phy_index], 153 &(fw_controller->smp_phy_array[smp_phy_index].list_element) 154 ); 155 156 //insert to owning device's smp phy list. 157 sci_fast_list_insert_tail( 158 (&(fw_controller->smp_phy_memory_list)), 159 (&(fw_controller->smp_phy_array[smp_phy_index].list_element)) 160 ); 161 } 162 163 scif_sas_controller_set_default_config_parameters(fw_controller); 164 165 fw_controller->internal_request_entries = 166 SCIF_SAS_MAX_INTERNAL_REQUEST_COUNT; 167 168 //@Todo: may need to verify all timers are released. Including domain's 169 //operation timer and all the Internal IO's timer. 170 171 //take care of the lock. 172 scif_cb_lock_disassociate(fw_controller, &fw_controller->hprq.lock); 173 } 174 175 /** 176 * @brief This method implements the actions taken when entering the 177 * INITIALIZING state. 178 * 179 * @param[in] object This parameter specifies the base object for which 180 * the state transition is occurring. This is cast into a 181 * SCIF_SAS_CONTROLLER object in the method implementation. 182 * 183 * @return none 184 */ 185 static 186 void scif_sas_controller_initializing_state_enter( 187 SCI_BASE_OBJECT_T * object 188 ) 189 { 190 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 191 192 SET_STATE_HANDLER( 193 fw_controller, 194 scif_sas_controller_state_handler_table, 195 SCI_BASE_CONTROLLER_STATE_INITIALIZING 196 ); 197 } 198 199 /** 200 * @brief This method implements the actions taken when entering the 201 * INITIALIZED state. 202 * 203 * @param[in] object This parameter specifies the base object for which 204 * the state transition is occurring. This is cast into a 205 * SCIF_SAS_CONTROLLER object in the method implementation. 206 * 207 * @return none 208 */ 209 static 210 void scif_sas_controller_initialized_state_enter( 211 SCI_BASE_OBJECT_T * object 212 ) 213 { 214 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 215 216 SET_STATE_HANDLER( 217 fw_controller, 218 scif_sas_controller_state_handler_table, 219 SCI_BASE_CONTROLLER_STATE_INITIALIZED 220 ); 221 } 222 223 /** 224 * @brief This method implements the actions taken when entering the 225 * STARTING state. 226 * 227 * @param[in] object This parameter specifies the base object for which 228 * the state transition is occurring. This is cast into a 229 * SCIF_SAS_CONTROLLER object in the method implementation. 230 * 231 * @return none 232 */ 233 static 234 void scif_sas_controller_starting_state_enter( 235 SCI_BASE_OBJECT_T * object 236 ) 237 { 238 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 239 240 SET_STATE_HANDLER( 241 fw_controller, 242 scif_sas_controller_state_handler_table, 243 SCI_BASE_CONTROLLER_STATE_STARTING 244 ); 245 } 246 247 /** 248 * @brief This method implements the actions taken when entering the 249 * READY state. 250 * 251 * @param[in] object This parameter specifies the base object for which 252 * the state transition is occurring. This is cast into a 253 * SCIF_SAS_CONTROLLER object in the method implementation. 254 * 255 * @return none 256 */ 257 static 258 void scif_sas_controller_ready_state_enter( 259 SCI_BASE_OBJECT_T * object 260 ) 261 { 262 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 263 264 SET_STATE_HANDLER( 265 fw_controller, 266 scif_sas_controller_state_handler_table, 267 SCI_BASE_CONTROLLER_STATE_READY 268 ); 269 } 270 271 /** 272 * @brief This method implements the actions taken when entering the 273 * STOPPING state. 274 * 275 * @param[in] object This parameter specifies the base object for which 276 * the state transition is occurring. This is cast into a 277 * SCIF_SAS_CONTROLLER object in the method implementation. 278 * 279 * @return none 280 */ 281 static 282 void scif_sas_controller_stopping_state_enter( 283 SCI_BASE_OBJECT_T * object 284 ) 285 { 286 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 287 288 SET_STATE_HANDLER( 289 fw_controller, 290 scif_sas_controller_state_handler_table, 291 SCI_BASE_CONTROLLER_STATE_STOPPING 292 ); 293 } 294 295 /** 296 * @brief This method implements the actions taken when entering the 297 * STOPPED state. 298 * 299 * @param[in] object This parameter specifies the base object for which 300 * the state transition is occurring. This is cast into a 301 * SCIF_SAS_CONTROLLER object in the method implementation. 302 * 303 * @return none 304 */ 305 static 306 void scif_sas_controller_stopped_state_enter( 307 SCI_BASE_OBJECT_T * object 308 ) 309 { 310 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 311 312 SET_STATE_HANDLER( 313 fw_controller, 314 scif_sas_controller_state_handler_table, 315 SCI_BASE_CONTROLLER_STATE_STOPPED 316 ); 317 } 318 319 /** 320 * @brief This method implements the actions taken when entering the 321 * RESETTING state. 322 * 323 * @param[in] object This parameter specifies the base object for which 324 * the state transition is occurring. This is cast into a 325 * SCIF_SAS_CONTROLLER object in the method implementation. 326 * 327 * @return none 328 */ 329 static 330 void scif_sas_controller_resetting_state_enter( 331 SCI_BASE_OBJECT_T * object 332 ) 333 { 334 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 335 336 SET_STATE_HANDLER( 337 fw_controller, 338 scif_sas_controller_state_handler_table, 339 SCI_BASE_CONTROLLER_STATE_RESETTING 340 ); 341 342 // Attempt to reset the core controller. 343 fw_controller->operation_status = scic_controller_reset( 344 fw_controller->core_object 345 ); 346 if (fw_controller->operation_status == SCI_SUCCESS) 347 { 348 // Reset the framework controller. 349 sci_base_state_machine_change_state( 350 &fw_controller->parent.state_machine, 351 SCI_BASE_CONTROLLER_STATE_RESET 352 ); 353 } 354 else 355 { 356 SCIF_LOG_ERROR(( 357 sci_base_object_get_logger(fw_controller), 358 SCIF_LOG_OBJECT_CONTROLLER, 359 "Controller: unable to successfully reset controller.\n" 360 )); 361 362 sci_base_state_machine_change_state( 363 &fw_controller->parent.state_machine, 364 SCI_BASE_CONTROLLER_STATE_FAILED 365 ); 366 } 367 } 368 369 /** 370 * @brief This method implements the actions taken when entering the 371 * FAILED state. 372 * 373 * @param[in] object This parameter specifies the base object for which 374 * the state transition is occurring. This is cast into a 375 * SCIF_SAS_CONTROLLER object in the method implementation. 376 * 377 * @return none 378 */ 379 static 380 void scif_sas_controller_failed_state_enter( 381 SCI_BASE_OBJECT_T * object 382 ) 383 { 384 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 385 386 SCIF_LOG_ERROR(( 387 sci_base_object_get_logger(fw_controller), 388 SCIF_LOG_OBJECT_CONTROLLER, 389 "Controller: entered FAILED state.\n" 390 )); 391 392 SET_STATE_HANDLER( 393 fw_controller, 394 scif_sas_controller_state_handler_table, 395 SCI_BASE_CONTROLLER_STATE_FAILED 396 ); 397 398 if (fw_controller->parent.error != SCI_CONTROLLER_FATAL_MEMORY_ERROR) 399 { 400 //clean timers to avoid timer leak. 401 scif_sas_controller_release_resource(fw_controller); 402 403 //notify user. 404 scif_cb_controller_error(fw_controller, fw_controller->parent.error); 405 } 406 } 407 408 SCI_BASE_STATE_T 409 scif_sas_controller_state_table[SCI_BASE_CONTROLLER_MAX_STATES] = 410 { 411 { 412 SCI_BASE_CONTROLLER_STATE_INITIAL, 413 scif_sas_controller_initial_state_enter, 414 NULL, 415 }, 416 { 417 SCI_BASE_CONTROLLER_STATE_RESET, 418 scif_sas_controller_reset_state_enter, 419 NULL, 420 }, 421 { 422 SCI_BASE_CONTROLLER_STATE_INITIALIZING, 423 scif_sas_controller_initializing_state_enter, 424 NULL, 425 }, 426 { 427 SCI_BASE_CONTROLLER_STATE_INITIALIZED, 428 scif_sas_controller_initialized_state_enter, 429 NULL, 430 }, 431 { 432 SCI_BASE_CONTROLLER_STATE_STARTING, 433 scif_sas_controller_starting_state_enter, 434 NULL, 435 }, 436 { 437 SCI_BASE_CONTROLLER_STATE_READY, 438 scif_sas_controller_ready_state_enter, 439 NULL, 440 }, 441 { 442 SCI_BASE_CONTROLLER_STATE_RESETTING, 443 scif_sas_controller_resetting_state_enter, 444 NULL, 445 }, 446 { 447 SCI_BASE_CONTROLLER_STATE_STOPPING, 448 scif_sas_controller_stopping_state_enter, 449 NULL, 450 }, 451 { 452 SCI_BASE_CONTROLLER_STATE_STOPPED, 453 scif_sas_controller_stopped_state_enter, 454 NULL, 455 }, 456 { 457 SCI_BASE_CONTROLLER_STATE_FAILED, 458 scif_sas_controller_failed_state_enter, 459 NULL, 460 } 461 }; 462 463