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 entrance and exit methods for each 60230557Sjimharris * of the controller states defined by the SCI_BASE_CONTROLLER state 61230557Sjimharris * machine. 62230557Sjimharris */ 63230557Sjimharris 64230557Sjimharris#include <dev/isci/scil/scic_controller.h> 65230557Sjimharris 66230557Sjimharris#include <dev/isci/scil/scif_sas_logger.h> 67230557Sjimharris#include <dev/isci/scil/scif_sas_controller.h> 68230557Sjimharris 69230557Sjimharris//****************************************************************************** 70230557Sjimharris//* P R O T E C T E D M E T H O D S 71230557Sjimharris//****************************************************************************** 72230557Sjimharris 73230557Sjimharris/** 74230557Sjimharris * @brief This method implements the actions taken when entering the 75230557Sjimharris * INITIAL state. 76230557Sjimharris * 77230557Sjimharris * @param[in] object This parameter specifies the base object for which 78230557Sjimharris * the state transition is occurring. This is cast into a 79230557Sjimharris * SCIF_SAS_CONTROLLER object in the method implementation. 80230557Sjimharris * 81230557Sjimharris * @return none 82230557Sjimharris */ 83230557Sjimharrisstatic 84230557Sjimharrisvoid scif_sas_controller_initial_state_enter( 85230557Sjimharris SCI_BASE_OBJECT_T * object 86230557Sjimharris) 87230557Sjimharris{ 88230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 89230557Sjimharris 90230557Sjimharris SET_STATE_HANDLER( 91230557Sjimharris fw_controller, 92230557Sjimharris scif_sas_controller_state_handler_table, 93230557Sjimharris SCI_BASE_CONTROLLER_STATE_INITIAL 94230557Sjimharris ); 95230557Sjimharris} 96230557Sjimharris 97230557Sjimharris/** 98230557Sjimharris * @brief This method implements the actions taken when entering the 99230557Sjimharris * RESET state. 100230557Sjimharris * 101230557Sjimharris * @param[in] object This parameter specifies the base object for which 102230557Sjimharris * the state transition is occurring. This is cast into a 103230557Sjimharris * SCIF_SAS_CONTROLLER object in the method implementation. 104230557Sjimharris * 105230557Sjimharris * @return none 106230557Sjimharris */ 107230557Sjimharrisstatic 108230557Sjimharrisvoid scif_sas_controller_reset_state_enter( 109230557Sjimharris SCI_BASE_OBJECT_T * object 110230557Sjimharris) 111230557Sjimharris{ 112230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 113230557Sjimharris U8 index; 114230557Sjimharris U16 smp_phy_index; 115230557Sjimharris 116230557Sjimharris SET_STATE_HANDLER( 117230557Sjimharris fw_controller, 118230557Sjimharris scif_sas_controller_state_handler_table, 119230557Sjimharris SCI_BASE_CONTROLLER_STATE_RESET 120230557Sjimharris ); 121230557Sjimharris 122230557Sjimharris scif_sas_high_priority_request_queue_construct( 123230557Sjimharris &fw_controller->hprq, sci_base_object_get_logger(fw_controller) 124230557Sjimharris ); 125230557Sjimharris 126230557Sjimharris // Construct the abstract element pool. This pool will store the 127230557Sjimharris // references to the framework's remote devices objects. 128230557Sjimharris sci_abstract_element_pool_construct( 129230557Sjimharris &fw_controller->free_remote_device_pool, 130230557Sjimharris fw_controller->remote_device_pool_elements, 131230557Sjimharris SCI_MAX_REMOTE_DEVICES 132230557Sjimharris ); 133230557Sjimharris 134230557Sjimharris // Construct the domain objects. 135230557Sjimharris for (index = 0; index < SCI_MAX_DOMAINS; index++) 136230557Sjimharris { 137230557Sjimharris scif_sas_domain_construct( 138230557Sjimharris &fw_controller->domains[index], index, fw_controller 139230557Sjimharris ); 140230557Sjimharris } 141230557Sjimharris 142230557Sjimharris //Initialize SMP PHY MEMORY LIST. 143230557Sjimharris sci_fast_list_init(&fw_controller->smp_phy_memory_list); 144230557Sjimharris 145230557Sjimharris for (smp_phy_index = 0; 146230557Sjimharris smp_phy_index < SCIF_SAS_SMP_PHY_COUNT; 147230557Sjimharris smp_phy_index++) 148230557Sjimharris { 149230557Sjimharris sci_fast_list_element_init( 150230557Sjimharris &fw_controller->smp_phy_array[smp_phy_index], 151230557Sjimharris &(fw_controller->smp_phy_array[smp_phy_index].list_element) 152230557Sjimharris ); 153230557Sjimharris 154230557Sjimharris //insert to owning device's smp phy list. 155230557Sjimharris sci_fast_list_insert_tail( 156230557Sjimharris (&(fw_controller->smp_phy_memory_list)), 157230557Sjimharris (&(fw_controller->smp_phy_array[smp_phy_index].list_element)) 158230557Sjimharris ); 159230557Sjimharris } 160230557Sjimharris 161230557Sjimharris scif_sas_controller_set_default_config_parameters(fw_controller); 162230557Sjimharris 163230557Sjimharris fw_controller->internal_request_entries = 164230557Sjimharris SCIF_SAS_MAX_INTERNAL_REQUEST_COUNT; 165230557Sjimharris 166230557Sjimharris //@Todo: may need to verify all timers are released. Including domain's 167230557Sjimharris //operation timer and all the Internal IO's timer. 168230557Sjimharris 169230557Sjimharris //take care of the lock. 170230557Sjimharris scif_cb_lock_disassociate(fw_controller, &fw_controller->hprq.lock); 171230557Sjimharris} 172230557Sjimharris 173230557Sjimharris/** 174230557Sjimharris * @brief This method implements the actions taken when entering the 175230557Sjimharris * INITIALIZING state. 176230557Sjimharris * 177230557Sjimharris * @param[in] object This parameter specifies the base object for which 178230557Sjimharris * the state transition is occurring. This is cast into a 179230557Sjimharris * SCIF_SAS_CONTROLLER object in the method implementation. 180230557Sjimharris * 181230557Sjimharris * @return none 182230557Sjimharris */ 183230557Sjimharrisstatic 184230557Sjimharrisvoid scif_sas_controller_initializing_state_enter( 185230557Sjimharris SCI_BASE_OBJECT_T * object 186230557Sjimharris) 187230557Sjimharris{ 188230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 189230557Sjimharris 190230557Sjimharris SET_STATE_HANDLER( 191230557Sjimharris fw_controller, 192230557Sjimharris scif_sas_controller_state_handler_table, 193230557Sjimharris SCI_BASE_CONTROLLER_STATE_INITIALIZING 194230557Sjimharris ); 195230557Sjimharris} 196230557Sjimharris 197230557Sjimharris/** 198230557Sjimharris * @brief This method implements the actions taken when entering the 199230557Sjimharris * INITIALIZED state. 200230557Sjimharris * 201230557Sjimharris * @param[in] object This parameter specifies the base object for which 202230557Sjimharris * the state transition is occurring. This is cast into a 203230557Sjimharris * SCIF_SAS_CONTROLLER object in the method implementation. 204230557Sjimharris * 205230557Sjimharris * @return none 206230557Sjimharris */ 207230557Sjimharrisstatic 208230557Sjimharrisvoid scif_sas_controller_initialized_state_enter( 209230557Sjimharris SCI_BASE_OBJECT_T * object 210230557Sjimharris) 211230557Sjimharris{ 212230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 213230557Sjimharris 214230557Sjimharris SET_STATE_HANDLER( 215230557Sjimharris fw_controller, 216230557Sjimharris scif_sas_controller_state_handler_table, 217230557Sjimharris SCI_BASE_CONTROLLER_STATE_INITIALIZED 218230557Sjimharris ); 219230557Sjimharris} 220230557Sjimharris 221230557Sjimharris/** 222230557Sjimharris * @brief This method implements the actions taken when entering the 223230557Sjimharris * STARTING state. 224230557Sjimharris * 225230557Sjimharris * @param[in] object This parameter specifies the base object for which 226230557Sjimharris * the state transition is occurring. This is cast into a 227230557Sjimharris * SCIF_SAS_CONTROLLER object in the method implementation. 228230557Sjimharris * 229230557Sjimharris * @return none 230230557Sjimharris */ 231230557Sjimharrisstatic 232230557Sjimharrisvoid scif_sas_controller_starting_state_enter( 233230557Sjimharris SCI_BASE_OBJECT_T * object 234230557Sjimharris) 235230557Sjimharris{ 236230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 237230557Sjimharris 238230557Sjimharris SET_STATE_HANDLER( 239230557Sjimharris fw_controller, 240230557Sjimharris scif_sas_controller_state_handler_table, 241230557Sjimharris SCI_BASE_CONTROLLER_STATE_STARTING 242230557Sjimharris ); 243230557Sjimharris} 244230557Sjimharris 245230557Sjimharris/** 246230557Sjimharris * @brief This method implements the actions taken when entering the 247230557Sjimharris * READY state. 248230557Sjimharris * 249230557Sjimharris * @param[in] object This parameter specifies the base object for which 250230557Sjimharris * the state transition is occurring. This is cast into a 251230557Sjimharris * SCIF_SAS_CONTROLLER object in the method implementation. 252230557Sjimharris * 253230557Sjimharris * @return none 254230557Sjimharris */ 255230557Sjimharrisstatic 256230557Sjimharrisvoid scif_sas_controller_ready_state_enter( 257230557Sjimharris SCI_BASE_OBJECT_T * object 258230557Sjimharris) 259230557Sjimharris{ 260230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 261230557Sjimharris 262230557Sjimharris SET_STATE_HANDLER( 263230557Sjimharris fw_controller, 264230557Sjimharris scif_sas_controller_state_handler_table, 265230557Sjimharris SCI_BASE_CONTROLLER_STATE_READY 266230557Sjimharris ); 267230557Sjimharris} 268230557Sjimharris 269230557Sjimharris/** 270230557Sjimharris * @brief This method implements the actions taken when entering the 271230557Sjimharris * STOPPING state. 272230557Sjimharris * 273230557Sjimharris * @param[in] object This parameter specifies the base object for which 274230557Sjimharris * the state transition is occurring. This is cast into a 275230557Sjimharris * SCIF_SAS_CONTROLLER object in the method implementation. 276230557Sjimharris * 277230557Sjimharris * @return none 278230557Sjimharris */ 279230557Sjimharrisstatic 280230557Sjimharrisvoid scif_sas_controller_stopping_state_enter( 281230557Sjimharris SCI_BASE_OBJECT_T * object 282230557Sjimharris) 283230557Sjimharris{ 284230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 285230557Sjimharris 286230557Sjimharris SET_STATE_HANDLER( 287230557Sjimharris fw_controller, 288230557Sjimharris scif_sas_controller_state_handler_table, 289230557Sjimharris SCI_BASE_CONTROLLER_STATE_STOPPING 290230557Sjimharris ); 291230557Sjimharris} 292230557Sjimharris 293230557Sjimharris/** 294230557Sjimharris * @brief This method implements the actions taken when entering the 295230557Sjimharris * STOPPED state. 296230557Sjimharris * 297230557Sjimharris * @param[in] object This parameter specifies the base object for which 298230557Sjimharris * the state transition is occurring. This is cast into a 299230557Sjimharris * SCIF_SAS_CONTROLLER object in the method implementation. 300230557Sjimharris * 301230557Sjimharris * @return none 302230557Sjimharris */ 303230557Sjimharrisstatic 304230557Sjimharrisvoid scif_sas_controller_stopped_state_enter( 305230557Sjimharris SCI_BASE_OBJECT_T * object 306230557Sjimharris) 307230557Sjimharris{ 308230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 309230557Sjimharris 310230557Sjimharris SET_STATE_HANDLER( 311230557Sjimharris fw_controller, 312230557Sjimharris scif_sas_controller_state_handler_table, 313230557Sjimharris SCI_BASE_CONTROLLER_STATE_STOPPED 314230557Sjimharris ); 315230557Sjimharris} 316230557Sjimharris 317230557Sjimharris/** 318230557Sjimharris * @brief This method implements the actions taken when entering the 319230557Sjimharris * RESETTING state. 320230557Sjimharris * 321230557Sjimharris * @param[in] object This parameter specifies the base object for which 322230557Sjimharris * the state transition is occurring. This is cast into a 323230557Sjimharris * SCIF_SAS_CONTROLLER object in the method implementation. 324230557Sjimharris * 325230557Sjimharris * @return none 326230557Sjimharris */ 327230557Sjimharrisstatic 328230557Sjimharrisvoid scif_sas_controller_resetting_state_enter( 329230557Sjimharris SCI_BASE_OBJECT_T * object 330230557Sjimharris) 331230557Sjimharris{ 332230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 333230557Sjimharris 334230557Sjimharris SET_STATE_HANDLER( 335230557Sjimharris fw_controller, 336230557Sjimharris scif_sas_controller_state_handler_table, 337230557Sjimharris SCI_BASE_CONTROLLER_STATE_RESETTING 338230557Sjimharris ); 339230557Sjimharris 340230557Sjimharris // Attempt to reset the core controller. 341230557Sjimharris fw_controller->operation_status = scic_controller_reset( 342230557Sjimharris fw_controller->core_object 343230557Sjimharris ); 344230557Sjimharris if (fw_controller->operation_status == SCI_SUCCESS) 345230557Sjimharris { 346230557Sjimharris // Reset the framework controller. 347230557Sjimharris sci_base_state_machine_change_state( 348230557Sjimharris &fw_controller->parent.state_machine, 349230557Sjimharris SCI_BASE_CONTROLLER_STATE_RESET 350230557Sjimharris ); 351230557Sjimharris } 352230557Sjimharris else 353230557Sjimharris { 354230557Sjimharris SCIF_LOG_ERROR(( 355230557Sjimharris sci_base_object_get_logger(fw_controller), 356230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER, 357230557Sjimharris "Controller: unable to successfully reset controller.\n" 358230557Sjimharris )); 359230557Sjimharris 360230557Sjimharris sci_base_state_machine_change_state( 361230557Sjimharris &fw_controller->parent.state_machine, 362230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED 363230557Sjimharris ); 364230557Sjimharris } 365230557Sjimharris} 366230557Sjimharris 367230557Sjimharris/** 368230557Sjimharris * @brief This method implements the actions taken when entering the 369230557Sjimharris * FAILED state. 370230557Sjimharris * 371230557Sjimharris * @param[in] object This parameter specifies the base object for which 372230557Sjimharris * the state transition is occurring. This is cast into a 373230557Sjimharris * SCIF_SAS_CONTROLLER object in the method implementation. 374230557Sjimharris * 375230557Sjimharris * @return none 376230557Sjimharris */ 377230557Sjimharrisstatic 378230557Sjimharrisvoid scif_sas_controller_failed_state_enter( 379230557Sjimharris SCI_BASE_OBJECT_T * object 380230557Sjimharris) 381230557Sjimharris{ 382230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object; 383230557Sjimharris 384230557Sjimharris SCIF_LOG_ERROR(( 385230557Sjimharris sci_base_object_get_logger(fw_controller), 386230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER, 387230557Sjimharris "Controller: entered FAILED state.\n" 388230557Sjimharris )); 389230557Sjimharris 390230557Sjimharris SET_STATE_HANDLER( 391230557Sjimharris fw_controller, 392230557Sjimharris scif_sas_controller_state_handler_table, 393230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED 394230557Sjimharris ); 395230557Sjimharris 396230557Sjimharris if (fw_controller->parent.error != SCI_CONTROLLER_FATAL_MEMORY_ERROR) 397230557Sjimharris { 398230557Sjimharris //clean timers to avoid timer leak. 399230557Sjimharris scif_sas_controller_release_resource(fw_controller); 400230557Sjimharris 401230557Sjimharris //notify user. 402230557Sjimharris scif_cb_controller_error(fw_controller, fw_controller->parent.error); 403230557Sjimharris } 404230557Sjimharris} 405230557Sjimharris 406230557SjimharrisSCI_BASE_STATE_T 407230557Sjimharrisscif_sas_controller_state_table[SCI_BASE_CONTROLLER_MAX_STATES] = 408230557Sjimharris{ 409230557Sjimharris { 410230557Sjimharris SCI_BASE_CONTROLLER_STATE_INITIAL, 411230557Sjimharris scif_sas_controller_initial_state_enter, 412230557Sjimharris NULL, 413230557Sjimharris }, 414230557Sjimharris { 415230557Sjimharris SCI_BASE_CONTROLLER_STATE_RESET, 416230557Sjimharris scif_sas_controller_reset_state_enter, 417230557Sjimharris NULL, 418230557Sjimharris }, 419230557Sjimharris { 420230557Sjimharris SCI_BASE_CONTROLLER_STATE_INITIALIZING, 421230557Sjimharris scif_sas_controller_initializing_state_enter, 422230557Sjimharris NULL, 423230557Sjimharris }, 424230557Sjimharris { 425230557Sjimharris SCI_BASE_CONTROLLER_STATE_INITIALIZED, 426230557Sjimharris scif_sas_controller_initialized_state_enter, 427230557Sjimharris NULL, 428230557Sjimharris }, 429230557Sjimharris { 430230557Sjimharris SCI_BASE_CONTROLLER_STATE_STARTING, 431230557Sjimharris scif_sas_controller_starting_state_enter, 432230557Sjimharris NULL, 433230557Sjimharris }, 434230557Sjimharris { 435230557Sjimharris SCI_BASE_CONTROLLER_STATE_READY, 436230557Sjimharris scif_sas_controller_ready_state_enter, 437230557Sjimharris NULL, 438230557Sjimharris }, 439230557Sjimharris { 440230557Sjimharris SCI_BASE_CONTROLLER_STATE_RESETTING, 441230557Sjimharris scif_sas_controller_resetting_state_enter, 442230557Sjimharris NULL, 443230557Sjimharris }, 444230557Sjimharris { 445230557Sjimharris SCI_BASE_CONTROLLER_STATE_STOPPING, 446230557Sjimharris scif_sas_controller_stopping_state_enter, 447230557Sjimharris NULL, 448230557Sjimharris }, 449230557Sjimharris { 450230557Sjimharris SCI_BASE_CONTROLLER_STATE_STOPPED, 451230557Sjimharris scif_sas_controller_stopped_state_enter, 452230557Sjimharris NULL, 453230557Sjimharris }, 454230557Sjimharris { 455230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED, 456230557Sjimharris scif_sas_controller_failed_state_enter, 457230557Sjimharris NULL, 458230557Sjimharris } 459230557Sjimharris}; 460230557Sjimharris 461