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 implementation of the SCIC_SDS_CONTROLLER 60230557Sjimharris * public, protected, and private methods. 61230557Sjimharris */ 62230557Sjimharris 63230557Sjimharris#include <dev/isci/types.h> 64230557Sjimharris#include <dev/isci/scil/sci_util.h> 65230557Sjimharris#include <dev/isci/scil/scic_controller.h> 66230557Sjimharris#include <dev/isci/scil/scic_port.h> 67230557Sjimharris#include <dev/isci/scil/scic_phy.h> 68230557Sjimharris#include <dev/isci/scil/scic_remote_device.h> 69230557Sjimharris#include <dev/isci/scil/scic_user_callback.h> 70230557Sjimharris#include <dev/isci/scil/scic_sds_pci.h> 71230557Sjimharris#include <dev/isci/scil/scic_sds_library.h> 72230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h> 73230557Sjimharris#include <dev/isci/scil/scic_sds_controller_registers.h> 74230557Sjimharris#include <dev/isci/scil/scic_sds_port.h> 75230557Sjimharris#include <dev/isci/scil/scic_sds_phy.h> 76230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h> 77230557Sjimharris#include <dev/isci/scil/scic_sds_request.h> 78230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h> 79230557Sjimharris#include <dev/isci/scil/scic_sds_port_configuration_agent.h> 80230557Sjimharris#include <dev/isci/scil/scu_constants.h> 81230557Sjimharris#include <dev/isci/scil/scu_event_codes.h> 82230557Sjimharris#include <dev/isci/scil/scu_completion_codes.h> 83230557Sjimharris#include <dev/isci/scil/scu_task_context.h> 84230557Sjimharris#include <dev/isci/scil/scu_remote_node_context.h> 85230557Sjimharris#include <dev/isci/scil/scu_unsolicited_frame.h> 86230557Sjimharris#include <dev/isci/scil/intel_pci.h> 87230557Sjimharris#include <dev/isci/scil/scic_sgpio.h> 88230557Sjimharris#include <dev/isci/scil/scic_sds_phy_registers.h> 89230557Sjimharris 90230557Sjimharris#define SCU_CONTEXT_RAM_INIT_STALL_TIME 200 91230557Sjimharris#define SCIC_SDS_CONTROLLER_MIN_TIMER_COUNT 3 92230557Sjimharris#define SCIC_SDS_CONTROLLER_MAX_TIMER_COUNT 3 93230557Sjimharris 94230557Sjimharris#define SCU_MAX_ZPT_DWORD_INDEX 131 95230557Sjimharris 96230557Sjimharris/** 97230557Sjimharris * The number of milliseconds to wait for a phy to start. 98230557Sjimharris */ 99230557Sjimharris#define SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT 100 100230557Sjimharris 101230557Sjimharris/** 102230557Sjimharris * The number of milliseconds to wait while a given phy is consuming 103230557Sjimharris * power before allowing another set of phys to consume power. 104230557Sjimharris * Ultimately, this will be specified by OEM parameter. 105230557Sjimharris */ 106230557Sjimharris#define SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL 500 107230557Sjimharris 108230557Sjimharris/** 109230557Sjimharris * This macro will return the cycle bit of the completion queue entry 110230557Sjimharris */ 111230557Sjimharris#define COMPLETION_QUEUE_CYCLE_BIT(x) ((x) & 0x80000000) 112230557Sjimharris 113230557Sjimharris/** 114230557Sjimharris * This macro will normalize the completion queue get pointer so its value 115230557Sjimharris * can be used as an index into an array 116230557Sjimharris */ 117230557Sjimharris#define NORMALIZE_GET_POINTER(x) \ 118230557Sjimharris ((x) & SMU_COMPLETION_QUEUE_GET_POINTER_MASK) 119230557Sjimharris 120230557Sjimharris/** 121230557Sjimharris * This macro will normalize the completion queue put pointer so its value 122230557Sjimharris * can be used as an array inde 123230557Sjimharris */ 124230557Sjimharris#define NORMALIZE_PUT_POINTER(x) \ 125230557Sjimharris ((x) & SMU_COMPLETION_QUEUE_PUT_POINTER_MASK) 126230557Sjimharris 127230557Sjimharris 128230557Sjimharris/** 129230557Sjimharris * This macro will normalize the completion queue cycle pointer so it 130230557Sjimharris * matches the completion queue cycle bit 131230557Sjimharris */ 132230557Sjimharris#define NORMALIZE_GET_POINTER_CYCLE_BIT(x) \ 133230557Sjimharris (((U32)(SMU_CQGR_CYCLE_BIT & (x))) << (31 - SMU_COMPLETION_QUEUE_GET_CYCLE_BIT_SHIFT)) 134230557Sjimharris 135230557Sjimharris/** 136230557Sjimharris * This macro will normalize the completion queue event entry so its value 137230557Sjimharris * can be used as an index. 138230557Sjimharris */ 139230557Sjimharris#define NORMALIZE_EVENT_POINTER(x) \ 140230557Sjimharris ( \ 141230557Sjimharris ((U32)((x) & SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_MASK)) \ 142230557Sjimharris >> SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_SHIFT \ 143230557Sjimharris ) 144230557Sjimharris 145230557Sjimharris/** 146230557Sjimharris * This macro will increment the controllers completion queue index value 147230557Sjimharris * and possibly toggle the cycle bit if the completion queue index wraps 148230557Sjimharris * back to 0. 149230557Sjimharris */ 150230557Sjimharris#define INCREMENT_COMPLETION_QUEUE_GET(controller, index, cycle) \ 151230557Sjimharris INCREMENT_QUEUE_GET( \ 152230557Sjimharris (index), \ 153230557Sjimharris (cycle), \ 154230557Sjimharris (controller)->completion_queue_entries, \ 155230557Sjimharris SMU_CQGR_CYCLE_BIT \ 156230557Sjimharris ) 157230557Sjimharris 158230557Sjimharris/** 159230557Sjimharris * This macro will increment the controllers event queue index value and 160230557Sjimharris * possibly toggle the event cycle bit if the event queue index wraps back 161230557Sjimharris * to 0. 162230557Sjimharris */ 163230557Sjimharris#define INCREMENT_EVENT_QUEUE_GET(controller, index, cycle) \ 164230557Sjimharris INCREMENT_QUEUE_GET( \ 165230557Sjimharris (index), \ 166230557Sjimharris (cycle), \ 167230557Sjimharris (controller)->completion_event_entries, \ 168230557Sjimharris SMU_CQGR_EVENT_CYCLE_BIT \ 169230557Sjimharris ) 170230557Sjimharris 171230557Sjimharris//****************************************************************************- 172230557Sjimharris//* SCIC SDS Controller Initialization Methods 173230557Sjimharris//****************************************************************************- 174230557Sjimharris 175230557Sjimharris/** 176230557Sjimharris * @brief This timer is used to start another phy after we have given up on 177230557Sjimharris * the previous phy to transition to the ready state. 178230557Sjimharris * 179230557Sjimharris * @param[in] controller 180230557Sjimharris */ 181230557Sjimharrisstatic 182230557Sjimharrisvoid scic_sds_controller_phy_startup_timeout_handler( 183230557Sjimharris void *controller 184230557Sjimharris) 185230557Sjimharris{ 186230557Sjimharris SCI_STATUS status; 187230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 188230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 189230557Sjimharris 190230557Sjimharris this_controller->phy_startup_timer_pending = FALSE; 191230557Sjimharris 192230557Sjimharris status = SCI_FAILURE; 193230557Sjimharris 194230557Sjimharris while (status != SCI_SUCCESS) 195230557Sjimharris { 196230557Sjimharris status = scic_sds_controller_start_next_phy(this_controller); 197230557Sjimharris } 198230557Sjimharris} 199230557Sjimharris 200230557Sjimharris/** 201230557Sjimharris * This method initializes the phy startup operations for controller start. 202230557Sjimharris * 203230557Sjimharris * @param this_controller 204230557Sjimharris */ 205230557Sjimharrisstatic 206230557SjimharrisSCI_STATUS scic_sds_controller_initialize_phy_startup( 207230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 208230557Sjimharris) 209230557Sjimharris{ 210230557Sjimharris this_controller->phy_startup_timer = scic_cb_timer_create( 211230557Sjimharris this_controller, 212230557Sjimharris scic_sds_controller_phy_startup_timeout_handler, 213230557Sjimharris this_controller 214230557Sjimharris ); 215230557Sjimharris 216230557Sjimharris if (this_controller->phy_startup_timer == NULL) 217230557Sjimharris { 218230557Sjimharris return SCI_FAILURE_INSUFFICIENT_RESOURCES; 219230557Sjimharris } 220230557Sjimharris else 221230557Sjimharris { 222230557Sjimharris this_controller->next_phy_to_start = 0; 223230557Sjimharris this_controller->phy_startup_timer_pending = FALSE; 224230557Sjimharris } 225230557Sjimharris 226230557Sjimharris return SCI_SUCCESS; 227230557Sjimharris} 228230557Sjimharris 229230557Sjimharris/** 230230557Sjimharris * This method initializes the power control operations for the controller 231230557Sjimharris * object. 232230557Sjimharris * 233230557Sjimharris * @param this_controller 234230557Sjimharris */ 235230557Sjimharrisvoid scic_sds_controller_initialize_power_control( 236230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 237230557Sjimharris) 238230557Sjimharris{ 239230557Sjimharris this_controller->power_control.timer = scic_cb_timer_create( 240230557Sjimharris this_controller, 241230557Sjimharris scic_sds_controller_power_control_timer_handler, 242230557Sjimharris this_controller 243230557Sjimharris ); 244230557Sjimharris 245230557Sjimharris memset( 246230557Sjimharris this_controller->power_control.requesters, 247230557Sjimharris 0, 248230557Sjimharris sizeof(this_controller->power_control.requesters) 249230557Sjimharris ); 250230557Sjimharris 251230557Sjimharris this_controller->power_control.phys_waiting = 0; 252230557Sjimharris this_controller->power_control.remote_devices_granted_power = 0; 253230557Sjimharris} 254230557Sjimharris 255230557Sjimharris// --------------------------------------------------------------------------- 256230557Sjimharris 257230557Sjimharris#define SCU_REMOTE_NODE_CONTEXT_ALIGNMENT (32) 258230557Sjimharris#define SCU_TASK_CONTEXT_ALIGNMENT (256) 259230557Sjimharris#define SCU_UNSOLICITED_FRAME_ADDRESS_ALIGNMENT (64) 260230557Sjimharris#define SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT (1024) 261230557Sjimharris#define SCU_UNSOLICITED_FRAME_HEADER_ALIGNMENT (64) 262230557Sjimharris 263230557Sjimharris// --------------------------------------------------------------------------- 264230557Sjimharris 265230557Sjimharris/** 266230557Sjimharris * @brief This method builds the memory descriptor table for this 267230557Sjimharris * controller. 268230557Sjimharris * 269230557Sjimharris * @param[in] this_controller This parameter specifies the controller 270230557Sjimharris * object for which to build the memory table. 271230557Sjimharris * 272230557Sjimharris * @return none 273230557Sjimharris */ 274230557Sjimharrisvoid scic_sds_controller_build_memory_descriptor_table( 275230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 276230557Sjimharris) 277230557Sjimharris{ 278230557Sjimharris sci_base_mde_construct( 279230557Sjimharris &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE], 280230557Sjimharris SCU_COMPLETION_RAM_ALIGNMENT, 281230557Sjimharris (sizeof(U32) * this_controller->completion_queue_entries), 282230557Sjimharris (SCI_MDE_ATTRIBUTE_CACHEABLE | SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS) 283230557Sjimharris ); 284230557Sjimharris 285230557Sjimharris sci_base_mde_construct( 286230557Sjimharris &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT], 287230557Sjimharris SCU_REMOTE_NODE_CONTEXT_ALIGNMENT, 288230557Sjimharris this_controller->remote_node_entries * sizeof(SCU_REMOTE_NODE_CONTEXT_T), 289230557Sjimharris SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS 290230557Sjimharris ); 291230557Sjimharris 292230557Sjimharris sci_base_mde_construct( 293230557Sjimharris &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT], 294230557Sjimharris SCU_TASK_CONTEXT_ALIGNMENT, 295230557Sjimharris this_controller->task_context_entries * sizeof(SCU_TASK_CONTEXT_T), 296230557Sjimharris SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS 297230557Sjimharris ); 298230557Sjimharris 299230557Sjimharris // The UF buffer address table size must be programmed to a power 300230557Sjimharris // of 2. Find the first power of 2 that is equal to or greater then 301230557Sjimharris // the number of unsolicited frame buffers to be utilized. 302230557Sjimharris scic_sds_unsolicited_frame_control_set_address_table_count( 303230557Sjimharris &this_controller->uf_control 304230557Sjimharris ); 305230557Sjimharris 306230557Sjimharris sci_base_mde_construct( 307230557Sjimharris &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER], 308230557Sjimharris SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT, 309230557Sjimharris scic_sds_unsolicited_frame_control_get_mde_size(this_controller->uf_control), 310230557Sjimharris SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS 311230557Sjimharris ); 312230557Sjimharris} 313230557Sjimharris 314230557Sjimharris/** 315230557Sjimharris * @brief This method validates the driver supplied memory descriptor 316230557Sjimharris * table. 317230557Sjimharris * 318230557Sjimharris * @param[in] this_controller 319230557Sjimharris * 320230557Sjimharris * @return SCI_STATUS 321230557Sjimharris */ 322230557SjimharrisSCI_STATUS scic_sds_controller_validate_memory_descriptor_table( 323230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 324230557Sjimharris) 325230557Sjimharris{ 326230557Sjimharris BOOL mde_list_valid; 327230557Sjimharris 328230557Sjimharris mde_list_valid = sci_base_mde_is_valid( 329230557Sjimharris &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE], 330230557Sjimharris SCU_COMPLETION_RAM_ALIGNMENT, 331230557Sjimharris (sizeof(U32) * this_controller->completion_queue_entries), 332230557Sjimharris (SCI_MDE_ATTRIBUTE_CACHEABLE | SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS) 333230557Sjimharris ); 334230557Sjimharris 335230557Sjimharris if (mde_list_valid == FALSE) 336230557Sjimharris return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD; 337230557Sjimharris 338230557Sjimharris mde_list_valid = sci_base_mde_is_valid( 339230557Sjimharris &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT], 340230557Sjimharris SCU_REMOTE_NODE_CONTEXT_ALIGNMENT, 341230557Sjimharris this_controller->remote_node_entries * sizeof(SCU_REMOTE_NODE_CONTEXT_T), 342230557Sjimharris SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS 343230557Sjimharris ); 344230557Sjimharris 345230557Sjimharris if (mde_list_valid == FALSE) 346230557Sjimharris return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD; 347230557Sjimharris 348230557Sjimharris mde_list_valid = sci_base_mde_is_valid( 349230557Sjimharris &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT], 350230557Sjimharris SCU_TASK_CONTEXT_ALIGNMENT, 351230557Sjimharris this_controller->task_context_entries * sizeof(SCU_TASK_CONTEXT_T), 352230557Sjimharris SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS 353230557Sjimharris ); 354230557Sjimharris 355230557Sjimharris if (mde_list_valid == FALSE) 356230557Sjimharris return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD; 357230557Sjimharris 358230557Sjimharris mde_list_valid = sci_base_mde_is_valid( 359230557Sjimharris &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER], 360230557Sjimharris SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT, 361230557Sjimharris scic_sds_unsolicited_frame_control_get_mde_size(this_controller->uf_control), 362230557Sjimharris SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS 363230557Sjimharris ); 364230557Sjimharris 365230557Sjimharris if (mde_list_valid == FALSE) 366230557Sjimharris return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD; 367230557Sjimharris 368230557Sjimharris return SCI_SUCCESS; 369230557Sjimharris} 370230557Sjimharris 371230557Sjimharris/** 372230557Sjimharris * @brief This method initializes the controller with the physical memory 373230557Sjimharris * addresses that are used to communicate with the driver. 374230557Sjimharris * 375230557Sjimharris * @param[in] this_controller 376230557Sjimharris * 377230557Sjimharris * @return none 378230557Sjimharris */ 379230557Sjimharrisvoid scic_sds_controller_ram_initialization( 380230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 381230557Sjimharris) 382230557Sjimharris{ 383230557Sjimharris SCI_PHYSICAL_MEMORY_DESCRIPTOR_T *mde; 384230557Sjimharris 385230557Sjimharris // The completion queue is actually placed in cacheable memory 386230557Sjimharris // Therefore it no longer comes out of memory in the MDL. 387230557Sjimharris mde = &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE]; 388230557Sjimharris this_controller->completion_queue = (U32*) mde->virtual_address; 389230557Sjimharris SMU_CQBAR_WRITE(this_controller, mde->physical_address); 390230557Sjimharris 391230557Sjimharris // Program the location of the Remote Node Context table 392230557Sjimharris // into the SCU. 393230557Sjimharris mde = &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT]; 394230557Sjimharris this_controller->remote_node_context_table = (SCU_REMOTE_NODE_CONTEXT_T *) 395230557Sjimharris mde->virtual_address; 396230557Sjimharris SMU_RNCBAR_WRITE(this_controller, mde->physical_address); 397230557Sjimharris 398230557Sjimharris // Program the location of the Task Context table into the SCU. 399230557Sjimharris mde = &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT]; 400230557Sjimharris this_controller->task_context_table = (SCU_TASK_CONTEXT_T *) 401230557Sjimharris mde->virtual_address; 402230557Sjimharris SMU_HTTBAR_WRITE(this_controller, mde->physical_address); 403230557Sjimharris 404230557Sjimharris mde = &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER]; 405230557Sjimharris scic_sds_unsolicited_frame_control_construct( 406230557Sjimharris &this_controller->uf_control, mde, this_controller 407230557Sjimharris ); 408230557Sjimharris 409230557Sjimharris // Inform the silicon as to the location of the UF headers and 410230557Sjimharris // address table. 411230557Sjimharris SCU_UFHBAR_WRITE( 412230557Sjimharris this_controller, 413230557Sjimharris this_controller->uf_control.headers.physical_address); 414230557Sjimharris SCU_PUFATHAR_WRITE( 415230557Sjimharris this_controller, 416230557Sjimharris this_controller->uf_control.address_table.physical_address); 417230557Sjimharris 418230557Sjimharris //enable the ECC correction and detection. 419230557Sjimharris SCU_SECR0_WRITE( 420230557Sjimharris this_controller, 421230557Sjimharris (SIGNLE_BIT_ERROR_CORRECTION_ENABLE 422230557Sjimharris | MULTI_BIT_ERROR_REPORTING_ENABLE 423230557Sjimharris | SINGLE_BIT_ERROR_REPORTING_ENABLE) ); 424230557Sjimharris SCU_SECR1_WRITE( 425230557Sjimharris this_controller, 426230557Sjimharris (SIGNLE_BIT_ERROR_CORRECTION_ENABLE 427230557Sjimharris | MULTI_BIT_ERROR_REPORTING_ENABLE 428230557Sjimharris | SINGLE_BIT_ERROR_REPORTING_ENABLE) ); 429230557Sjimharris} 430230557Sjimharris 431230557Sjimharris/** 432230557Sjimharris * @brief This method initializes the task context data for the controller. 433230557Sjimharris * 434230557Sjimharris * @param[in] this_controller 435230557Sjimharris * 436230557Sjimharris * @return none 437230557Sjimharris */ 438230557Sjimharrisvoid scic_sds_controller_assign_task_entries( 439230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 440230557Sjimharris) 441230557Sjimharris{ 442230557Sjimharris U32 task_assignment; 443230557Sjimharris 444230557Sjimharris // Assign all the TCs to function 0 445230557Sjimharris // TODO: Do we actually need to read this register to write it back? 446230557Sjimharris task_assignment = SMU_TCA_READ(this_controller, 0); 447230557Sjimharris 448230557Sjimharris task_assignment = 449230557Sjimharris ( 450230557Sjimharris task_assignment 451230557Sjimharris | (SMU_TCA_GEN_VAL(STARTING, 0)) 452230557Sjimharris | (SMU_TCA_GEN_VAL(ENDING, this_controller->task_context_entries - 1)) 453230557Sjimharris | (SMU_TCA_GEN_BIT(RANGE_CHECK_ENABLE)) 454230557Sjimharris ); 455230557Sjimharris 456230557Sjimharris SMU_TCA_WRITE(this_controller, 0, task_assignment); 457230557Sjimharris} 458230557Sjimharris 459230557Sjimharris/** 460230557Sjimharris * @brief This method initializes the hardware completion queue. 461230557Sjimharris * 462230557Sjimharris * @param[in] this_controller 463230557Sjimharris */ 464230557Sjimharrisvoid scic_sds_controller_initialize_completion_queue( 465230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 466230557Sjimharris) 467230557Sjimharris{ 468230557Sjimharris U32 index; 469230557Sjimharris U32 completion_queue_control_value; 470230557Sjimharris U32 completion_queue_get_value; 471230557Sjimharris U32 completion_queue_put_value; 472230557Sjimharris 473230557Sjimharris this_controller->completion_queue_get = 0; 474230557Sjimharris 475230557Sjimharris completion_queue_control_value = ( 476230557Sjimharris SMU_CQC_QUEUE_LIMIT_SET(this_controller->completion_queue_entries - 1) 477230557Sjimharris | SMU_CQC_EVENT_LIMIT_SET(this_controller->completion_event_entries - 1) 478230557Sjimharris ); 479230557Sjimharris 480230557Sjimharris SMU_CQC_WRITE(this_controller, completion_queue_control_value); 481230557Sjimharris 482230557Sjimharris // Set the completion queue get pointer and enable the queue 483230557Sjimharris completion_queue_get_value = ( 484230557Sjimharris (SMU_CQGR_GEN_VAL(POINTER, 0)) 485230557Sjimharris | (SMU_CQGR_GEN_VAL(EVENT_POINTER, 0)) 486230557Sjimharris | (SMU_CQGR_GEN_BIT(ENABLE)) 487230557Sjimharris | (SMU_CQGR_GEN_BIT(EVENT_ENABLE)) 488230557Sjimharris ); 489230557Sjimharris 490230557Sjimharris SMU_CQGR_WRITE(this_controller, completion_queue_get_value); 491230557Sjimharris 492230557Sjimharris this_controller->completion_queue_get = completion_queue_get_value; 493230557Sjimharris 494230557Sjimharris // Set the completion queue put pointer 495230557Sjimharris completion_queue_put_value = ( 496230557Sjimharris (SMU_CQPR_GEN_VAL(POINTER, 0)) 497230557Sjimharris | (SMU_CQPR_GEN_VAL(EVENT_POINTER, 0)) 498230557Sjimharris ); 499230557Sjimharris 500230557Sjimharris SMU_CQPR_WRITE(this_controller, completion_queue_put_value); 501230557Sjimharris 502230557Sjimharris // Initialize the cycle bit of the completion queue entries 503230557Sjimharris for (index = 0; index < this_controller->completion_queue_entries; index++) 504230557Sjimharris { 505230557Sjimharris // If get.cycle_bit != completion_queue.cycle_bit 506230557Sjimharris // its not a valid completion queue entry 507230557Sjimharris // so at system start all entries are invalid 508230557Sjimharris this_controller->completion_queue[index] = 0x80000000; 509230557Sjimharris } 510230557Sjimharris} 511230557Sjimharris 512230557Sjimharris/** 513230557Sjimharris * @brief This method initializes the hardware unsolicited frame queue. 514230557Sjimharris * 515230557Sjimharris * @param[in] this_controller 516230557Sjimharris */ 517230557Sjimharrisvoid scic_sds_controller_initialize_unsolicited_frame_queue( 518230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 519230557Sjimharris) 520230557Sjimharris{ 521230557Sjimharris U32 frame_queue_control_value; 522230557Sjimharris U32 frame_queue_get_value; 523230557Sjimharris U32 frame_queue_put_value; 524230557Sjimharris 525230557Sjimharris // Write the queue size 526230557Sjimharris frame_queue_control_value = 527230557Sjimharris SCU_UFQC_GEN_VAL(QUEUE_SIZE, this_controller->uf_control.address_table.count); 528230557Sjimharris 529230557Sjimharris SCU_UFQC_WRITE(this_controller, frame_queue_control_value); 530230557Sjimharris 531230557Sjimharris // Setup the get pointer for the unsolicited frame queue 532230557Sjimharris frame_queue_get_value = ( 533230557Sjimharris SCU_UFQGP_GEN_VAL(POINTER, 0) 534230557Sjimharris | SCU_UFQGP_GEN_BIT(ENABLE_BIT) 535230557Sjimharris ); 536230557Sjimharris 537230557Sjimharris SCU_UFQGP_WRITE(this_controller, frame_queue_get_value); 538230557Sjimharris 539230557Sjimharris // Setup the put pointer for the unsolicited frame queue 540230557Sjimharris frame_queue_put_value = SCU_UFQPP_GEN_VAL(POINTER, 0); 541230557Sjimharris 542230557Sjimharris SCU_UFQPP_WRITE(this_controller, frame_queue_put_value); 543230557Sjimharris} 544230557Sjimharris 545230557Sjimharris/** 546230557Sjimharris * @brief This method enables the hardware port task scheduler. 547230557Sjimharris * 548230557Sjimharris * @param[in] this_controller 549230557Sjimharris */ 550230557Sjimharrisvoid scic_sds_controller_enable_port_task_scheduler( 551230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 552230557Sjimharris) 553230557Sjimharris{ 554230557Sjimharris U32 port_task_scheduler_value; 555230557Sjimharris 556230557Sjimharris port_task_scheduler_value = SCU_PTSGCR_READ(this_controller); 557230557Sjimharris 558230557Sjimharris port_task_scheduler_value |= 559230557Sjimharris (SCU_PTSGCR_GEN_BIT(ETM_ENABLE) | SCU_PTSGCR_GEN_BIT(PTSG_ENABLE)); 560230557Sjimharris 561230557Sjimharris SCU_PTSGCR_WRITE(this_controller, port_task_scheduler_value); 562230557Sjimharris} 563230557Sjimharris 564230557Sjimharris// --------------------------------------------------------------------------- 565230557Sjimharris 566230557Sjimharris#ifdef ARLINGTON_BUILD 567230557Sjimharris/** 568230557Sjimharris * This method will read from the lexington status register. This is required 569230557Sjimharris * as a read fence to the lexington register writes. 570230557Sjimharris * 571230557Sjimharris * @param this_controller 572230557Sjimharris */ 573230557Sjimharrisvoid scic_sds_controller_lex_status_read_fence( 574230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 575230557Sjimharris) 576230557Sjimharris{ 577230557Sjimharris U32 lex_status; 578230557Sjimharris 579230557Sjimharris // Read Fence 580230557Sjimharris lex_status = lex_register_read( 581230557Sjimharris this_controller, this_controller->lex_registers + 0xC4); 582230557Sjimharris 583230557Sjimharris SCIC_LOG_TRACE(( 584230557Sjimharris sci_base_object_get_logger(this_controller), 585230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 586230557Sjimharris "Controller 0x%x lex_status = 0x%08x\n", 587230557Sjimharris this_controller, lex_status 588230557Sjimharris )); 589230557Sjimharris} 590230557Sjimharris 591230557Sjimharris/** 592230557Sjimharris * This method will initialize the arlington through the LEX_BAR. 593230557Sjimharris * 594230557Sjimharris * @param this_controller 595230557Sjimharris */ 596230557Sjimharrisvoid scic_sds_controller_lex_atux_initialization( 597230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 598230557Sjimharris) 599230557Sjimharris{ 600230557Sjimharris // 1. Reset all SCU PHY 601230557Sjimharris lex_register_write( 602230557Sjimharris this_controller, this_controller->lex_registers + 0x28, 0x0020FFFF) ; 603230557Sjimharris 604230557Sjimharris // 2. Write to LEX_CTRL 605230557Sjimharris lex_register_write( 606230557Sjimharris this_controller, this_controller->lex_registers + 0xC0, 0x00000700); 607230557Sjimharris 608230557Sjimharris scic_sds_controller_lex_status_read_fence(this_controller); 609230557Sjimharris 610230557Sjimharris // 3. Enable PCI Master 611230557Sjimharris lex_register_write( 612230557Sjimharris this_controller, this_controller->lex_registers + 0x70, 0x00000002); 613230557Sjimharris 614230557Sjimharris // 4. Enable SCU Register Clock Domain 615230557Sjimharris lex_register_write( 616230557Sjimharris this_controller, this_controller->lex_registers + 0xC0, 0x00000300); 617230557Sjimharris 618230557Sjimharris scic_sds_controller_lex_status_read_fence(this_controller); 619230557Sjimharris 620230557Sjimharris // 5.1 Release PHY-A Reg Reset 621230557Sjimharris lex_register_write( 622230557Sjimharris this_controller, this_controller->lex_registers + 0x28, 0x0000FFFF); 623230557Sjimharris 624230557Sjimharris // 5.2 Initialize the AFE for PHY-A 625230557Sjimharris scic_sds_controller_afe_initialization(this_controller); 626230557Sjimharris 627230557Sjimharris scic_sds_controller_lex_status_read_fence(this_controller); 628230557Sjimharris 629230557Sjimharris#if 0 630230557Sjimharris // 5.3 Release PHY Reg Reset 631230557Sjimharris lex_register_write( 632230557Sjimharris this_controller, this_controller->lex_registers + 0x28, 0x0000FFFF); 633230557Sjimharris#endif 634230557Sjimharris 635230557Sjimharris // 6.1 Release PHY-B Reg Reset 636230557Sjimharris lex_register_write( 637230557Sjimharris this_controller, this_controller->lex_registers + 0x28, 0x0040FFFF) ; 638230557Sjimharris 639230557Sjimharris // 6.2 Initialize the AFE for PHY-B 640230557Sjimharris scic_sds_controller_afe_initialization(this_controller); 641230557Sjimharris 642230557Sjimharris scic_sds_controller_lex_status_read_fence(this_controller); 643230557Sjimharris 644230557Sjimharris#if 0 645230557Sjimharris // 6.3 Release PHY-B Reg Reset 646230557Sjimharris lex_register_write( 647230557Sjimharris this_controller, this_controller->lex_registers + 0x28, 0x0040FFFF) ; 648230557Sjimharris#endif 649230557Sjimharris 650230557Sjimharris // 7. Enable SCU clock domaion 651230557Sjimharris lex_register_write( 652230557Sjimharris this_controller, this_controller->lex_registers + 0xC0, 0x00000100); 653230557Sjimharris 654230557Sjimharris scic_sds_controller_lex_status_read_fence(this_controller); 655230557Sjimharris 656230557Sjimharris // 8. Release LEX SCU Reset 657230557Sjimharris lex_register_write( 658230557Sjimharris this_controller, this_controller->lex_registers + 0xC0, 0x00000000); 659230557Sjimharris 660230557Sjimharris scic_sds_controller_lex_status_read_fence(this_controller); 661230557Sjimharris 662230557Sjimharris#if !defined(DISABLE_INTERRUPTS) 663230557Sjimharris // 8a. Set legacy interrupts (SCU INTx to PCI-x INTA) 664230557Sjimharris lex_register_write( 665230557Sjimharris this_controller, this_controller->lex_registers + 0xC0, 0x00000800); 666230557Sjimharris 667230557Sjimharris scic_sds_controller_lex_status_read_fence(this_controller); 668230557Sjimharris#endif 669230557Sjimharris 670230557Sjimharris#if 0 671230557Sjimharris // 9. Override TXOLVL 672230557Sjimharris //write to lex_ctrl 673230557Sjimharris lex_register_write( 674230557Sjimharris this_controller, this_controller->lex_registers + 0xC0, 0x27800000); 675230557Sjimharris#endif 676230557Sjimharris 677230557Sjimharris // 10. Release PHY-A & PHY-B Resets 678230557Sjimharris lex_register_write( 679230557Sjimharris this_controller, this_controller->lex_registers + 0x28, 0x0000FF77); 680230557Sjimharris 681230557Sjimharris lex_register_write( 682230557Sjimharris this_controller, this_controller->lex_registers + 0x28, 0x0000FF55); 683230557Sjimharris 684230557Sjimharris lex_register_write( 685230557Sjimharris this_controller, this_controller->lex_registers + 0x28, 0x0000FF11); 686230557Sjimharris 687230557Sjimharris lex_register_write( 688230557Sjimharris this_controller, this_controller->lex_registers + 0x28, 0x0000FF00); 689230557Sjimharris 690230557Sjimharris lex_register_write( 691230557Sjimharris this_controller, this_controller->lex_registers + 0x28, 0x0003FF00); 692230557Sjimharris} 693230557Sjimharris#endif // ARLINGTON_BUILD 694230557Sjimharris 695230557Sjimharris// --------------------------------------------------------------------------- 696230557Sjimharris 697230557Sjimharris#ifdef ARLINGTON_BUILD 698230557Sjimharris/** 699230557Sjimharris * This method enables chipwatch on the arlington board 700230557Sjimharris * 701230557Sjimharris * @param[in] this_controller 702230557Sjimharris */ 703230557Sjimharrisvoid scic_sds_controller_enable_chipwatch( 704230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 705230557Sjimharris) 706230557Sjimharris{ 707230557Sjimharris lex_register_write( 708230557Sjimharris this_controller, this_controller->lex_registers + 0x88, 0x09090909); 709230557Sjimharris 710230557Sjimharris lex_register_write( 711230557Sjimharris this_controller, this_controller->lex_registers + 0x8C, 0xcac9c862); 712230557Sjimharris} 713230557Sjimharris#endif 714230557Sjimharris 715230557Sjimharris/** 716230557Sjimharris * This macro is used to delay between writes to the AFE registers 717230557Sjimharris * during AFE initialization. 718230557Sjimharris */ 719230557Sjimharris#define AFE_REGISTER_WRITE_DELAY 10 720230557Sjimharris 721230557Sjimharris/** 722230557Sjimharris * Initialize the AFE for this phy index. 723230557Sjimharris * 724230557Sjimharris * @todo We need to read the AFE setup from the OEM parameters 725230557Sjimharris * 726230557Sjimharris * @param[in] this_controller 727230557Sjimharris * 728230557Sjimharris * @return none 729230557Sjimharris */ 730230557Sjimharris#if defined(ARLINGTON_BUILD) 731230557Sjimharrisvoid scic_sds_controller_afe_initialization( 732230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 733230557Sjimharris) 734230557Sjimharris{ 735230557Sjimharris // 1. Establish Power 736230557Sjimharris // Hold Bias, PLL, and RX TX in reset and powerdown 737230557Sjimharris // pe_afe0_rst_n = 0 738230557Sjimharris // pe_afe0_txpdn0,1,2,3 = 1 739230557Sjimharris // pe_afe0_rxpdn0,1,2,3 = 1 740230557Sjimharris // pe_afe0_txrst0,1,2,3_n = 0 741230557Sjimharris // pe_afe0_rxrst0,1,2,3_n = 0 742230557Sjimharris // wait 1us 743230557Sjimharris // pe_afe0_rst_n = 1 744230557Sjimharris // wait 1us 745230557Sjimharris scu_afe_register_write( 746230557Sjimharris this_controller, afe_pll_control, 0x00247506); 747230557Sjimharris 748230557Sjimharris // 2. Write 0x00000000 to AFE XCVR Ctrl2 749230557Sjimharris scu_afe_register_write( 750230557Sjimharris this_controller, afe_dfx_transceiver_status_clear, 0x00000000); 751230557Sjimharris 752230557Sjimharris // 3. afe0_override_en = 0 753230557Sjimharris // afe0_pll_dis_override = 0 754230557Sjimharris // afe0_tx_rst_override = 0 755230557Sjimharris // afe0_pll_dis = 1 756230557Sjimharris // pe_afe0_txrate = 01 757230557Sjimharris // pe_afe0_rxrate = 01 758230557Sjimharris // pe_afe0_txdis = 11 759230557Sjimharris // pe_afe0_txoob = 1 760230557Sjimharris // pe_afe0_txovlv = 9'b001110000 761230557Sjimharris scu_afe_register_write( 762230557Sjimharris this_controller, afe_transceiver_control0[0], 0x0700141e); 763230557Sjimharris 764230557Sjimharris // 4. Configure PLL Unit 765230557Sjimharris // Write 0x00200506 to AFE PLL Ctrl Register 0 766230557Sjimharris scu_afe_register_write(this_controller, afe_pll_control, 0x00200506); 767230557Sjimharris scu_afe_register_write(this_controller, afe_pll_dfx_control, 0x10000080); 768230557Sjimharris 769230557Sjimharris // 5. Configure Bias Unit 770230557Sjimharris scu_afe_register_write(this_controller, afe_bias_control[0], 0x00124814); 771230557Sjimharris scu_afe_register_write(this_controller, afe_bias_control[1], 0x24900000); 772230557Sjimharris 773230557Sjimharris // 6. Configure Transceiver Units 774230557Sjimharris scu_afe_register_write( 775230557Sjimharris this_controller, afe_transceiver_control0[0], 0x0702941e); 776230557Sjimharris 777230557Sjimharris scu_afe_register_write( 778230557Sjimharris this_controller, afe_transceiver_control1[0], 0x0000000a); 779230557Sjimharris 780230557Sjimharris // 7. Configure RX Units 781230557Sjimharris scu_afe_register_write( 782230557Sjimharris this_controller, afe_transceiver_equalization_control[0], 0x00ba2223); 783230557Sjimharris 784230557Sjimharris scu_afe_register_write( 785230557Sjimharris this_controller, reserved_0028_003c[2], 0x00000000); 786230557Sjimharris 787230557Sjimharris // 8. Configure TX Units 788230557Sjimharris scu_afe_register_write( 789230557Sjimharris this_controller, afe_dfx_transmit_control_register[0], 0x03815428); 790230557Sjimharris 791230557Sjimharris // 9. Transfer control to PE signals 792230557Sjimharris scu_afe_register_write( 793230557Sjimharris this_controller, afe_dfx_transceiver_status_clear, 0x00000010); 794230557Sjimharris 795230557Sjimharris // 10. Release PLL Powerdown 796230557Sjimharris scu_afe_register_write(this_controller, afe_pll_control, 0x00200504); 797230557Sjimharris 798230557Sjimharris // 11. Release PLL Reset 799230557Sjimharris scu_afe_register_write(this_controller, afe_pll_control, 0x00200505); 800230557Sjimharris 801230557Sjimharris // 12. Wait for PLL to Lock 802230557Sjimharris // (afe0_comm_sta [1:0] should go to 1'b11, and 803230557Sjimharris // [5:2] is 0x5, 0x6, 0x7, 0x8, or 0x9 804230557Sjimharris scu_afe_register_write(this_controller, afe_pll_control, 0x00200501); 805230557Sjimharris 806230557Sjimharris while ((scu_afe_register_read(this_controller, afe_common_status) & 0x03) != 0x03) 807230557Sjimharris { 808230557Sjimharris // Give time for the PLLs to lock 809230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 810230557Sjimharris } 811230557Sjimharris 812230557Sjimharris // 13. pe_afe0_rxpdn0 = 0 813230557Sjimharris // pe_afe0_rxrst0 = 1 814230557Sjimharris // pe_afe0_txrst0_n = 1 815230557Sjimharris // pe_afe_txoob0_n = 0 816230557Sjimharris scu_afe_register_write( 817230557Sjimharris this_controller, afe_transceiver_control0[0], 0x07028c11); 818230557Sjimharris} 819230557Sjimharris 820230557Sjimharris#elif defined(PLEASANT_RIDGE_BUILD) 821230557Sjimharris 822230557Sjimharrisvoid scic_sds_controller_afe_initialization( 823230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 824230557Sjimharris) 825230557Sjimharris{ 826230557Sjimharris U32 afe_status; 827230557Sjimharris U32 phy_id; 828230557Sjimharris 829230557Sjimharris#if defined(SPREADSHEET_AFE_SETTINGS) 830230557Sjimharris // Clear DFX Status registers 831230557Sjimharris scu_afe_register_write( 832230557Sjimharris this_controller, afe_dfx_master_control0, 0x0000000f); 833230557Sjimharris // Configure bias currents to normal 834230557Sjimharris scu_afe_register_write( 835230557Sjimharris this_controller, afe_bias_control, 0x0000aa00); 836230557Sjimharris // Enable PLL 837230557Sjimharris scu_afe_register_write( 838230557Sjimharris this_controller, afe_pll_control0, 0x80000908); 839230557Sjimharris 840230557Sjimharris // Wait for the PLL to lock 841230557Sjimharris do 842230557Sjimharris { 843230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 844230557Sjimharris afe_status = scu_afe_register_read( 845230557Sjimharris this_controller, afe_common_block_status); 846230557Sjimharris } 847230557Sjimharris while((afe_status & 0x00001000) == 0); 848230557Sjimharris 849230557Sjimharris for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) 850230557Sjimharris { 851230557Sjimharris // Initialize transceiver channels 852230557Sjimharris scu_afe_register_write( 853230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_channel_control, 0x00000157); 854230557Sjimharris // Configure transceiver modes 855230557Sjimharris scu_afe_register_write( 856230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x38016d1a); 857230557Sjimharris // Configure receiver parameters 858230557Sjimharris scu_afe_register_write( 859230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control1, 0x01501014); 860230557Sjimharris // Configure transmitter parameters 861230557Sjimharris scu_afe_register_write( 862230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_control, 0x00000000); 863230557Sjimharris // Configure transmitter equalization 864230557Sjimharris scu_afe_register_write( 865230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control0, 0x000bdd08); 866230557Sjimharris scu_afe_register_write( 867230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control1, 0x000ffc00); 868230557Sjimharris scu_afe_register_write( 869230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control2, 0x000b7c09); 870230557Sjimharris scu_afe_register_write( 871230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control3, 0x000afc6e); 872230557Sjimharris // Configure transmitter SSC parameters 873230557Sjimharris scu_afe_register_write( 874230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_ssc_control, 0x00000000); 875230557Sjimharris // Configure receiver parameters 876230557Sjimharris scu_afe_register_write( 877230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 0x3208903f); 878230557Sjimharris 879230557Sjimharris // Start power on sequence 880230557Sjimharris // Enable bias currents to transceivers and wait 200ns 881230557Sjimharris scu_afe_register_write( 882230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_channel_control, 0x00000154); 883230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 884230557Sjimharris // Take receiver out of power down and wait 200ns 885230557Sjimharris scu_afe_register_write( 886230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x3801611a); 887230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 888230557Sjimharris // Take receiver out of reset and wait 200ns 889230557Sjimharris scu_afe_register_write( 890230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x3801631a); 891230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 892230557Sjimharris // Take transmitter out of power down and wait 200ns 893230557Sjimharris scu_afe_register_write( 894230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x38016318); 895230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 896230557Sjimharris // Take transmitter out of reset and wait 200ns 897230557Sjimharris scu_afe_register_write( 898230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x38016319); 899230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 900230557Sjimharris // Take transmitter out of DC idle 901230557Sjimharris scu_afe_register_write( 902230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x38016319); 903230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 904230557Sjimharris } 905230557Sjimharris 906230557Sjimharris // Transfer control to the PEs 907230557Sjimharris scu_afe_register_write( 908230557Sjimharris this_controller, afe_dfx_master_control0, 0x00010f00); 909230557Sjimharris#else // !defined(SPREADSHEET_AFE_SETTINGS) 910230557Sjimharris // These are the AFEE settings used by the SV group 911230557Sjimharris // Clear DFX Status registers 912230557Sjimharris scu_afe_register_write( 913230557Sjimharris this_controller, afe_dfx_master_control0, 0x0081000f); 914230557Sjimharris // Configure bias currents to normal 915230557Sjimharris scu_afe_register_write( 916230557Sjimharris this_controller, afe_bias_control, 0x0000aa00); 917230557Sjimharris // Enable PLL 918230557Sjimharris scu_afe_register_write( 919230557Sjimharris this_controller, afe_pll_control0, 0x80000908); 920230557Sjimharris 921230557Sjimharris // Wait for the PLL to lock 922230557Sjimharris // Note: this is done later in the SV shell script however this looks 923230557Sjimharris // like the location to do this since we have enabled the PLL. 924230557Sjimharris do 925230557Sjimharris { 926230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 927230557Sjimharris afe_status = scu_afe_register_read( 928230557Sjimharris this_controller, afe_common_block_status); 929230557Sjimharris } 930230557Sjimharris while((afe_status & 0x00001000) == 0); 931230557Sjimharris 932230557Sjimharris // Make sure BIST is disabled 933230557Sjimharris scu_afe_register_write( 934230557Sjimharris this_controller, afe_dfx_master_control1, 0x00000000); 935230557Sjimharris // Shorten SAS SNW lock time 936230557Sjimharris scu_afe_register_write( 937230557Sjimharris this_controller, afe_pmsn_master_control0, 0x7bd316ad); 938230557Sjimharris 939230557Sjimharris for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) 940230557Sjimharris { 941230557Sjimharris // Initialize transceiver channels 942230557Sjimharris scu_afe_register_write( 943230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_channel_control, 0x00000174); 944230557Sjimharris // Configure SSC control 945230557Sjimharris scu_afe_register_write( 946230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_ssc_control, 0x00030000); 947230557Sjimharris // Configure transceiver modes 948230557Sjimharris scu_afe_register_write( 949230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x0000651a); 950230557Sjimharris // Power up TX RX and RX OOB 951230557Sjimharris scu_afe_register_write( 952230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006518); 953230557Sjimharris // Enable RX OOB Detect 954230557Sjimharris scu_afe_register_write( 955230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006518); 956230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 957230557Sjimharris #if 0 958230557Sjimharris // Configure transmitter parameters 959230557Sjimharris scu_afe_register_write( 960230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_control, 0x00000000); 961230557Sjimharris // Configure transmitter equalization 962230557Sjimharris scu_afe_register_write( 963230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control0, 0x000bdd08); 964230557Sjimharris scu_afe_register_write( 965230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control1, 0x000ffc00); 966230557Sjimharris scu_afe_register_write( 967230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control2, 0x000b7c09); 968230557Sjimharris scu_afe_register_write( 969230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control3, 0x000afc6e); 970230557Sjimharris // Configure transmitter SSC parameters 971230557Sjimharris // Power up TX RX 972230557Sjimharris 973230557Sjimharris scu_afe_register_write( 974230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_channel_control, 0x00000154); 975230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 976230557Sjimharris 977230557Sjimharris // FFE = Max 978230557Sjimharris scu_afe_register_write( 979230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_dfx_rx_control1, 0x00000080); 980230557Sjimharris // DFE1-5 = small 981230557Sjimharris scu_afe_register_write( 982230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_dfx_rx_control1, 0x01041042); 983230557Sjimharris // Enable DFE/FFE and freeze 984230557Sjimharris scu_afe_register_write( 985230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 0x320891bf); 986230557Sjimharris #endif 987230557Sjimharris // Take receiver out of power down and wait 200ns 988230557Sjimharris scu_afe_register_write( 989230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006118); 990230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 991230557Sjimharris // TX Electrical Idle 992230557Sjimharris scu_afe_register_write( 993230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006108); 994230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 995230557Sjimharris 996230557Sjimharris // Leave DFE/FFE on 997230557Sjimharris scu_afe_register_write( 998230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 0x0317108f); 999230557Sjimharris 1000230557Sjimharris // Configure receiver parameters 1001230557Sjimharris scu_afe_register_write( 1002230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control1, 0x01e00021); 1003230557Sjimharris 1004230557Sjimharris // Bring RX out of reset 1005230557Sjimharris scu_afe_register_write( 1006230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006109); 1007230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1008230557Sjimharris 1009230557Sjimharris scu_afe_register_write( 1010230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006009); 1011230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1012230557Sjimharris 1013230557Sjimharris scu_afe_register_write( 1014230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006209); 1015230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1016230557Sjimharris } 1017230557Sjimharris 1018230557Sjimharris // Transfer control to the PEs 1019230557Sjimharris scu_afe_register_write( 1020230557Sjimharris this_controller, afe_dfx_master_control0, 0x00010f00); 1021230557Sjimharris#endif 1022230557Sjimharris} 1023230557Sjimharris 1024230557Sjimharris#elif defined(PBG_HBA_A0_BUILD) || defined(PBG_HBA_A2_BUILD) || defined(PBG_HBA_BETA_BUILD) || defined(PBG_BUILD) 1025230557Sjimharris 1026230557Sjimharrisvoid scic_sds_controller_afe_initialization( 1027230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 1028230557Sjimharris) 1029230557Sjimharris{ 1030230557Sjimharris U32 afe_status; 1031230557Sjimharris U32 phy_id; 1032230557Sjimharris U8 cable_selection_mask; 1033230557Sjimharris 1034230557Sjimharris if ( 1035230557Sjimharris (this_controller->pci_revision != SCIC_SDS_PCI_REVISION_A0) 1036230557Sjimharris && (this_controller->pci_revision != SCIC_SDS_PCI_REVISION_A2) 1037230557Sjimharris && (this_controller->pci_revision != SCIC_SDS_PCI_REVISION_B0) 1038230557Sjimharris && (this_controller->pci_revision != SCIC_SDS_PCI_REVISION_C0) 1039230557Sjimharris && (this_controller->pci_revision != SCIC_SDS_PCI_REVISION_C1) 1040230557Sjimharris ) 1041230557Sjimharris { 1042230557Sjimharris // A programming bug has occurred if we are attempting to 1043230557Sjimharris // support a PCI revision other than those listed. Default 1044230557Sjimharris // to B0, and attempt to limp along if it isn't B0. 1045230557Sjimharris ASSERT(FALSE); 1046230557Sjimharris this_controller->pci_revision = SCIC_SDS_PCI_REVISION_C1; 1047230557Sjimharris } 1048230557Sjimharris 1049230557Sjimharris cable_selection_mask = 1050230557Sjimharris this_controller->oem_parameters.sds1.controller.cable_selection_mask; 1051230557Sjimharris 1052230557Sjimharris // These are the AFEE settings used by the SV group 1053230557Sjimharris // Clear DFX Status registers 1054230557Sjimharris scu_afe_register_write( 1055230557Sjimharris this_controller, afe_dfx_master_control0, 0x0081000f); 1056230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1057230557Sjimharris 1058230557Sjimharris if ( 1059230557Sjimharris (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0) 1060230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0) 1061230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1) 1062230557Sjimharris ) 1063230557Sjimharris { 1064230557Sjimharris // PM Rx Equalization Save, PM SPhy Rx Acknowledgement Timer, PM Stagger Timer 1065230557Sjimharris scu_afe_register_write( 1066230557Sjimharris this_controller, afe_pmsn_master_control2, 0x0007FFFF); 1067230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1068230557Sjimharris } 1069230557Sjimharris 1070230557Sjimharris // Configure bias currents to normal 1071230557Sjimharris if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0) 1072230557Sjimharris scu_afe_register_write(this_controller, afe_bias_control, 0x00005500); 1073230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) 1074230557Sjimharris scu_afe_register_write(this_controller, afe_bias_control, 0x00005A00); 1075230557Sjimharris else if ( (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0) 1076230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0) ) 1077230557Sjimharris scu_afe_register_write(this_controller, afe_bias_control, 0x00005F00); 1078230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1) 1079230557Sjimharris scu_afe_register_write(this_controller, afe_bias_control, 0x00005500); 1080230557Sjimharris // For C0 the AFE BIAS Controll is unchanged 1081230557Sjimharris 1082230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1083230557Sjimharris 1084230557Sjimharris // Enable PLL 1085230557Sjimharris if ( (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0) 1086230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) ) 1087230557Sjimharris { 1088230557Sjimharris scu_afe_register_write(this_controller, afe_pll_control0, 0x80040908); 1089230557Sjimharris } 1090230557Sjimharris else if ( (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0) 1091230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0) ) 1092230557Sjimharris { 1093230557Sjimharris scu_afe_register_write(this_controller, afe_pll_control0, 0x80040A08); 1094230557Sjimharris } 1095230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1) 1096230557Sjimharris { 1097230557Sjimharris scu_afe_register_write(this_controller, afe_pll_control0, 0x80000b08); 1098230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1099230557Sjimharris scu_afe_register_write(this_controller, afe_pll_control0, 0x00000b08); 1100230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1101230557Sjimharris scu_afe_register_write(this_controller, afe_pll_control0, 0x80000b08); 1102230557Sjimharris } 1103230557Sjimharris 1104230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1105230557Sjimharris 1106230557Sjimharris // Wait for the PLL to lock 1107230557Sjimharris // Note: this is done later in the SV shell script however this looks 1108230557Sjimharris // like the location to do this since we have enabled the PLL. 1109230557Sjimharris do 1110230557Sjimharris { 1111230557Sjimharris afe_status = scu_afe_register_read( 1112230557Sjimharris this_controller, afe_common_block_status); 1113230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1114230557Sjimharris } 1115230557Sjimharris while((afe_status & 0x00001000) == 0); 1116230557Sjimharris 1117230557Sjimharris if ( (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0) 1118230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) ) 1119230557Sjimharris { 1120230557Sjimharris // Shorten SAS SNW lock time (RxLock timer value from 76 us to 50 us) 1121230557Sjimharris scu_afe_register_write( 1122230557Sjimharris this_controller, afe_pmsn_master_control0, 0x7bcc96ad); 1123230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1124230557Sjimharris } 1125230557Sjimharris 1126230557Sjimharris for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) 1127230557Sjimharris { 1128230557Sjimharris U8 cable_length_long = (cable_selection_mask >> phy_id) & 1; 1129230557Sjimharris U8 cable_length_medium = (cable_selection_mask >> (phy_id + 4)) & 1; 1130230557Sjimharris 1131230557Sjimharris if ( (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0) 1132230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) ) 1133230557Sjimharris { 1134230557Sjimharris // All defaults, except the Receive Word Alignament/Comma Detect 1135230557Sjimharris // Enable....(0xe800) 1136230557Sjimharris scu_afe_register_write( 1137230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00004512 1138230557Sjimharris ); 1139230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1140230557Sjimharris 1141230557Sjimharris scu_afe_register_write( 1142230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control1, 0x0050100F 1143230557Sjimharris ); 1144230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1145230557Sjimharris } 1146230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0) 1147230557Sjimharris { 1148230557Sjimharris // Configure transmitter SSC parameters 1149230557Sjimharris scu_afe_register_write( 1150230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_ssc_control, 0x00030000 1151230557Sjimharris ); 1152230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1153230557Sjimharris } 1154230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0) 1155230557Sjimharris { 1156230557Sjimharris // Configure transmitter SSC parameters 1157230557Sjimharris scu_afe_register_write( 1158230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_ssc_control, 0x00010202 1159230557Sjimharris ); 1160230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1161230557Sjimharris 1162230557Sjimharris // All defaults, except the Receive Word Alignament/Comma Detect 1163230557Sjimharris // Enable....(0xe800) 1164230557Sjimharris scu_afe_register_write( 1165230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00014500 1166230557Sjimharris ); 1167230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1168230557Sjimharris } 1169230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1) 1170230557Sjimharris { 1171230557Sjimharris // Configure transmitter SSC parameters 1172230557Sjimharris scu_afe_register_write( 1173230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_ssc_control, 0x00010202 1174230557Sjimharris ); 1175230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1176230557Sjimharris 1177230557Sjimharris // All defaults, except the Receive Word Alignament/Comma Detect 1178230557Sjimharris // Enable....(0xe800) 1179230557Sjimharris scu_afe_register_write( 1180230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x0001C500 1181230557Sjimharris ); 1182230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1183230557Sjimharris } 1184230557Sjimharris // Power up TX and RX out from power down (PWRDNTX and PWRDNRX) 1185230557Sjimharris // & increase TX int & ext bias 20%....(0xe85c) 1186230557Sjimharris if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0) 1187230557Sjimharris { 1188230557Sjimharris scu_afe_register_write( 1189230557Sjimharris this_controller, 1190230557Sjimharris scu_afe_xcvr[phy_id].afe_channel_control, 1191230557Sjimharris 0x000003D4 1192230557Sjimharris ); 1193230557Sjimharris } 1194230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) 1195230557Sjimharris { 1196230557Sjimharris scu_afe_register_write( 1197230557Sjimharris this_controller, 1198230557Sjimharris scu_afe_xcvr[phy_id].afe_channel_control, 1199230557Sjimharris 0x000003F0 1200230557Sjimharris ); 1201230557Sjimharris } 1202230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0) 1203230557Sjimharris { 1204230557Sjimharris // Power down TX and RX (PWRDNTX and PWRDNRX) 1205230557Sjimharris scu_afe_register_write( 1206230557Sjimharris this_controller, 1207230557Sjimharris scu_afe_xcvr[phy_id].afe_channel_control, 1208230557Sjimharris 0x000003d7 1209230557Sjimharris ); 1210230557Sjimharris 1211230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1212230557Sjimharris 1213230557Sjimharris // Power up TX and RX out from power down (PWRDNTX and PWRDNRX) 1214230557Sjimharris // & increase TX int & ext bias 20%....(0xe85c) 1215230557Sjimharris scu_afe_register_write( 1216230557Sjimharris this_controller, 1217230557Sjimharris scu_afe_xcvr[phy_id].afe_channel_control, 1218230557Sjimharris 0x000003d4 1219230557Sjimharris ); 1220230557Sjimharris } 1221230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0) 1222230557Sjimharris { 1223230557Sjimharris scu_afe_register_write( 1224230557Sjimharris this_controller, 1225230557Sjimharris scu_afe_xcvr[phy_id].afe_channel_control, 1226230557Sjimharris 0x000001e7 1227230557Sjimharris ); 1228230557Sjimharris 1229230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1230230557Sjimharris 1231230557Sjimharris // Power up TX and RX out from power down (PWRDNTX and PWRDNRX) 1232230557Sjimharris // & increase TX int & ext bias 20%....(0xe85c) 1233230557Sjimharris scu_afe_register_write( 1234230557Sjimharris this_controller, 1235230557Sjimharris scu_afe_xcvr[phy_id].afe_channel_control, 1236230557Sjimharris 0x000001e4 1237230557Sjimharris ); 1238230557Sjimharris } 1239230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1) 1240230557Sjimharris { 1241230557Sjimharris scu_afe_register_write( 1242230557Sjimharris this_controller, 1243230557Sjimharris scu_afe_xcvr[phy_id].afe_channel_control, 1244230557Sjimharris cable_length_long ? 0x000002F7 : 1245230557Sjimharris cable_length_medium ? 0x000001F7 : 0x000001F7 1246230557Sjimharris ); 1247230557Sjimharris 1248230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1249230557Sjimharris 1250230557Sjimharris // Power up TX and RX out from power down (PWRDNTX and PWRDNRX) 1251230557Sjimharris // & increase TX int & ext bias 20%....(0xe85c) 1252230557Sjimharris scu_afe_register_write( 1253230557Sjimharris this_controller, 1254230557Sjimharris scu_afe_xcvr[phy_id].afe_channel_control, 1255230557Sjimharris cable_length_long ? 0x000002F4 : 1256230557Sjimharris cable_length_medium ? 0x000001F4 : 0x000001F4 1257230557Sjimharris ); 1258230557Sjimharris } 1259230557Sjimharris 1260230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1261230557Sjimharris 1262230557Sjimharris if ( (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0) 1263230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) ) 1264230557Sjimharris { 1265230557Sjimharris // Enable TX equalization (0xe824) 1266230557Sjimharris scu_afe_register_write( 1267230557Sjimharris this_controller, 1268230557Sjimharris scu_afe_xcvr[phy_id].afe_tx_control, 1269230557Sjimharris 0x00040000 1270230557Sjimharris ); 1271230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1272230557Sjimharris } 1273230557Sjimharris 1274230557Sjimharris if ( (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0) 1275230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) 1276230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0) ) 1277230557Sjimharris { 1278230557Sjimharris // RDPI=0x0(RX Power On), RXOOBDETPDNC=0x0, TPD=0x0(TX Power On), 1279230557Sjimharris // RDD=0x0(RX Detect Enabled) ....(0xe800) 1280230557Sjimharris scu_afe_register_write( 1281230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00004100); 1282230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1283230557Sjimharris } 1284230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0) 1285230557Sjimharris { 1286230557Sjimharris scu_afe_register_write( 1287230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00014100); 1288230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1289230557Sjimharris } 1290230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1) 1291230557Sjimharris { 1292230557Sjimharris scu_afe_register_write( 1293230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x0001c100); 1294230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1295230557Sjimharris } 1296230557Sjimharris 1297230557Sjimharris // Leave DFE/FFE on 1298230557Sjimharris if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0) 1299230557Sjimharris { 1300230557Sjimharris scu_afe_register_write( 1301230557Sjimharris this_controller, 1302230557Sjimharris scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 1303230557Sjimharris 0x3F09983F 1304230557Sjimharris ); 1305230557Sjimharris } 1306230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) 1307230557Sjimharris { 1308230557Sjimharris scu_afe_register_write( 1309230557Sjimharris this_controller, 1310230557Sjimharris scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 1311230557Sjimharris 0x3F11103F 1312230557Sjimharris ); 1313230557Sjimharris } 1314230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0) 1315230557Sjimharris { 1316230557Sjimharris scu_afe_register_write( 1317230557Sjimharris this_controller, 1318230557Sjimharris scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 1319230557Sjimharris 0x3F11103F 1320230557Sjimharris ); 1321230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1322230557Sjimharris 1323230557Sjimharris // Enable TX equalization (0xe824) 1324230557Sjimharris scu_afe_register_write( 1325230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_control, 0x00040000); 1326230557Sjimharris } 1327230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0) 1328230557Sjimharris { 1329230557Sjimharris scu_afe_register_write( 1330230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control1, 0x01400c0f); 1331230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1332230557Sjimharris 1333230557Sjimharris scu_afe_register_write( 1334230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 0x3f6f103f); 1335230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1336230557Sjimharris 1337230557Sjimharris // Enable TX equalization (0xe824) 1338230557Sjimharris scu_afe_register_write( 1339230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_control, 0x00040000); 1340230557Sjimharris } 1341230557Sjimharris else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1) 1342230557Sjimharris { 1343230557Sjimharris scu_afe_register_write( 1344230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control1, 1345230557Sjimharris cable_length_long ? 0x01500C0C : 1346230557Sjimharris cable_length_medium ? 0x01400C0D : 0x02400C0D 1347230557Sjimharris ); 1348230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1349230557Sjimharris 1350230557Sjimharris scu_afe_register_write( 1351230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_dfx_rx_control1, 0x000003e0); 1352230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1353230557Sjimharris 1354230557Sjimharris scu_afe_register_write( 1355230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 1356230557Sjimharris cable_length_long ? 0x33091C1F : 1357230557Sjimharris cable_length_medium ? 0x3315181F : 0x2B17161F 1358230557Sjimharris ); 1359230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1360230557Sjimharris 1361230557Sjimharris // Enable TX equalization (0xe824) 1362230557Sjimharris scu_afe_register_write( 1363230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_control, 0x00040000); 1364230557Sjimharris } 1365230557Sjimharris 1366230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1367230557Sjimharris 1368230557Sjimharris scu_afe_register_write( 1369230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control0, 1370230557Sjimharris this_controller->oem_parameters.sds1.phys[phy_id].afe_tx_amp_control0 1371230557Sjimharris ); 1372230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1373230557Sjimharris 1374230557Sjimharris scu_afe_register_write( 1375230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control1, 1376230557Sjimharris this_controller->oem_parameters.sds1.phys[phy_id].afe_tx_amp_control1 1377230557Sjimharris ); 1378230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1379230557Sjimharris 1380230557Sjimharris scu_afe_register_write( 1381230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control2, 1382230557Sjimharris this_controller->oem_parameters.sds1.phys[phy_id].afe_tx_amp_control2 1383230557Sjimharris ); 1384230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1385230557Sjimharris 1386230557Sjimharris scu_afe_register_write( 1387230557Sjimharris this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control3, 1388230557Sjimharris this_controller->oem_parameters.sds1.phys[phy_id].afe_tx_amp_control3 1389230557Sjimharris ); 1390230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1391230557Sjimharris } 1392230557Sjimharris 1393230557Sjimharris // Transfer control to the PEs 1394230557Sjimharris scu_afe_register_write( 1395230557Sjimharris this_controller, afe_dfx_master_control0, 0x00010f00); 1396230557Sjimharris scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY); 1397230557Sjimharris} 1398230557Sjimharris#else 1399230557Sjimharris #error "Unsupported board type" 1400230557Sjimharris#endif 1401230557Sjimharris 1402230557Sjimharris//****************************************************************************- 1403230557Sjimharris//* SCIC SDS Controller Internal Start/Stop Routines 1404230557Sjimharris//****************************************************************************- 1405230557Sjimharris 1406230557Sjimharris 1407230557Sjimharris/** 1408230557Sjimharris * @brief This method will attempt to transition into the ready state 1409230557Sjimharris * for the controller and indicate that the controller start 1410230557Sjimharris * operation has completed if all criteria are met. 1411230557Sjimharris * 1412230557Sjimharris * @param[in,out] this_controller This parameter indicates the controller 1413230557Sjimharris * object for which to transition to ready. 1414230557Sjimharris * @param[in] status This parameter indicates the status value to be 1415230557Sjimharris * pass into the call to scic_cb_controller_start_complete(). 1416230557Sjimharris * 1417230557Sjimharris * @return none. 1418230557Sjimharris */ 1419230557Sjimharrisstatic 1420230557Sjimharrisvoid scic_sds_controller_transition_to_ready( 1421230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 1422230557Sjimharris SCI_STATUS status 1423230557Sjimharris) 1424230557Sjimharris{ 1425230557Sjimharris SCIC_LOG_TRACE(( 1426230557Sjimharris sci_base_object_get_logger(this_controller), 1427230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 1428230557Sjimharris "scic_sds_controller_transition_to_ready(0x%x, 0x%x) enter\n", 1429230557Sjimharris this_controller, status 1430230557Sjimharris )); 1431230557Sjimharris 1432230557Sjimharris if (this_controller->parent.state_machine.current_state_id 1433230557Sjimharris == SCI_BASE_CONTROLLER_STATE_STARTING) 1434230557Sjimharris { 1435230557Sjimharris // We move into the ready state, because some of the phys/ports 1436230557Sjimharris // may be up and operational. 1437230557Sjimharris sci_base_state_machine_change_state( 1438230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 1439230557Sjimharris SCI_BASE_CONTROLLER_STATE_READY 1440230557Sjimharris ); 1441230557Sjimharris 1442230557Sjimharris scic_cb_controller_start_complete(this_controller, status); 1443230557Sjimharris } 1444230557Sjimharris} 1445230557Sjimharris 1446230557Sjimharris/** 1447230557Sjimharris * @brief This method is the general timeout handler for the controller. 1448230557Sjimharris * It will take the correct timetout action based on the current 1449230557Sjimharris * controller state 1450230557Sjimharris * 1451230557Sjimharris * @param[in] controller This parameter indicates the controller on which 1452230557Sjimharris * a timeout occurred. 1453230557Sjimharris * 1454230557Sjimharris * @return none 1455230557Sjimharris */ 1456230557Sjimharrisvoid scic_sds_controller_timeout_handler( 1457230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 1458230557Sjimharris) 1459230557Sjimharris{ 1460230557Sjimharris SCI_BASE_CONTROLLER_STATES current_state; 1461230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 1462230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 1463230557Sjimharris 1464230557Sjimharris current_state = sci_base_state_machine_get_state( 1465230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller) 1466230557Sjimharris ); 1467230557Sjimharris 1468230557Sjimharris if (current_state == SCI_BASE_CONTROLLER_STATE_STARTING) 1469230557Sjimharris { 1470230557Sjimharris scic_sds_controller_transition_to_ready( 1471230557Sjimharris this_controller, SCI_FAILURE_TIMEOUT 1472230557Sjimharris ); 1473230557Sjimharris } 1474230557Sjimharris else if (current_state == SCI_BASE_CONTROLLER_STATE_STOPPING) 1475230557Sjimharris { 1476230557Sjimharris sci_base_state_machine_change_state( 1477230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 1478230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED 1479230557Sjimharris ); 1480230557Sjimharris 1481230557Sjimharris scic_cb_controller_stop_complete(controller, SCI_FAILURE_TIMEOUT); 1482230557Sjimharris } 1483230557Sjimharris else 1484230557Sjimharris { 1485230557Sjimharris /// @todo Now what do we want to do in this case? 1486230557Sjimharris SCIC_LOG_ERROR(( 1487230557Sjimharris sci_base_object_get_logger(this_controller), 1488230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 1489230557Sjimharris "Controller timer fired when controller was not in a state being timed.\n" 1490230557Sjimharris )); 1491230557Sjimharris } 1492230557Sjimharris} 1493230557Sjimharris 1494230557Sjimharris/** 1495230557Sjimharris * @brief 1496230557Sjimharris * 1497230557Sjimharris * @param[in] this_controller 1498230557Sjimharris * 1499230557Sjimharris * @return SCI_STATUS 1500230557Sjimharris */ 1501230557SjimharrisSCI_STATUS scic_sds_controller_stop_ports( 1502230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 1503230557Sjimharris) 1504230557Sjimharris{ 1505230557Sjimharris U32 index; 1506230557Sjimharris SCI_STATUS status; 1507230557Sjimharris SCI_STATUS port_status; 1508230557Sjimharris 1509230557Sjimharris status = SCI_SUCCESS; 1510230557Sjimharris 1511230557Sjimharris for (index = 0; index < this_controller->logical_port_entries; index++) 1512230557Sjimharris { 1513230557Sjimharris port_status = this_controller->port_table[index]. 1514230557Sjimharris state_handlers->parent.stop_handler(&this_controller->port_table[index].parent); 1515230557Sjimharris if ( 1516230557Sjimharris (port_status != SCI_SUCCESS) 1517230557Sjimharris && (port_status != SCI_FAILURE_INVALID_STATE) 1518230557Sjimharris ) 1519230557Sjimharris { 1520230557Sjimharris status = SCI_FAILURE; 1521230557Sjimharris 1522230557Sjimharris SCIC_LOG_WARNING(( 1523230557Sjimharris sci_base_object_get_logger(this_controller), 1524230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_PORT, 1525230557Sjimharris "Controller stop operation failed to stop port %d because of status %d.\n", 1526230557Sjimharris this_controller->port_table[index].logical_port_index, port_status 1527230557Sjimharris )); 1528230557Sjimharris } 1529230557Sjimharris } 1530230557Sjimharris 1531230557Sjimharris return status; 1532230557Sjimharris} 1533230557Sjimharris 1534230557Sjimharris/** 1535230557Sjimharris * @brief 1536230557Sjimharris * 1537230557Sjimharris * @param[in] this_controller 1538230557Sjimharris */ 1539230557Sjimharrisstatic 1540230557Sjimharrisvoid scic_sds_controller_phy_timer_start( 1541230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 1542230557Sjimharris) 1543230557Sjimharris{ 1544230557Sjimharris scic_cb_timer_start( 1545230557Sjimharris this_controller, 1546230557Sjimharris this_controller->phy_startup_timer, 1547230557Sjimharris SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT 1548230557Sjimharris ); 1549230557Sjimharris 1550230557Sjimharris this_controller->phy_startup_timer_pending = TRUE; 1551230557Sjimharris} 1552230557Sjimharris 1553230557Sjimharris/** 1554230557Sjimharris * @brief 1555230557Sjimharris * 1556230557Sjimharris * @param[in] this_controller 1557230557Sjimharris */ 1558230557Sjimharrisvoid scic_sds_controller_phy_timer_stop( 1559230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 1560230557Sjimharris) 1561230557Sjimharris{ 1562230557Sjimharris scic_cb_timer_stop( 1563230557Sjimharris this_controller, 1564230557Sjimharris this_controller->phy_startup_timer 1565230557Sjimharris ); 1566230557Sjimharris 1567230557Sjimharris this_controller->phy_startup_timer_pending = FALSE; 1568230557Sjimharris} 1569230557Sjimharris 1570230557Sjimharris/** 1571230557Sjimharris * @brief This method is called internally to determine whether the 1572230557Sjimharris * controller start process is complete. This is only true when: 1573230557Sjimharris * - all links have been given an opportunity to start 1574230557Sjimharris * - have no indication of a connected device 1575230557Sjimharris * - have an indication of a connected device and it has 1576230557Sjimharris * finished the link training process. 1577230557Sjimharris * 1578230557Sjimharris * @param[in] this_controller This parameter specifies the controller 1579230557Sjimharris * object for which to start the next phy. 1580230557Sjimharris * 1581230557Sjimharris * @return BOOL 1582230557Sjimharris */ 1583230557SjimharrisBOOL scic_sds_controller_is_start_complete( 1584230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 1585230557Sjimharris) 1586230557Sjimharris{ 1587230557Sjimharris U8 index; 1588230557Sjimharris 1589230557Sjimharris for (index = 0; index < SCI_MAX_PHYS; index++) 1590230557Sjimharris { 1591230557Sjimharris SCIC_SDS_PHY_T *the_phy = & this_controller->phy_table[index]; 1592230557Sjimharris 1593230557Sjimharris if ( 1594230557Sjimharris ( 1595230557Sjimharris this_controller->oem_parameters.sds1.controller.mode_type 1596230557Sjimharris == SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE 1597230557Sjimharris ) 1598230557Sjimharris || ( 1599230557Sjimharris ( 1600230557Sjimharris this_controller->oem_parameters.sds1.controller.mode_type 1601230557Sjimharris == SCIC_PORT_MANUAL_CONFIGURATION_MODE 1602230557Sjimharris ) 1603230557Sjimharris && (scic_sds_phy_get_port(the_phy) != SCI_INVALID_HANDLE) 1604230557Sjimharris ) 1605230557Sjimharris ) 1606230557Sjimharris { 1607230557Sjimharris /** 1608230557Sjimharris * The controller start operation is complete if and only 1609230557Sjimharris * if: 1610230557Sjimharris * - all links have been given an opportunity to start 1611230557Sjimharris * - have no indication of a connected device 1612230557Sjimharris * - have an indication of a connected device and it has 1613230557Sjimharris * finished the link training process. 1614230557Sjimharris */ 1615230557Sjimharris if ( 1616230557Sjimharris ( 1617230557Sjimharris (the_phy->is_in_link_training == FALSE) 1618230557Sjimharris && (the_phy->parent.state_machine.current_state_id 1619230557Sjimharris == SCI_BASE_PHY_STATE_INITIAL) 1620230557Sjimharris ) 1621230557Sjimharris || ( 1622230557Sjimharris (the_phy->is_in_link_training == FALSE) 1623230557Sjimharris && (the_phy->parent.state_machine.current_state_id 1624230557Sjimharris == SCI_BASE_PHY_STATE_STOPPED) 1625230557Sjimharris ) 1626230557Sjimharris || ( 1627230557Sjimharris (the_phy->is_in_link_training == TRUE) 1628230557Sjimharris && (the_phy->parent.state_machine.current_state_id 1629230557Sjimharris == SCI_BASE_PHY_STATE_STARTING) 1630230557Sjimharris ) 1631230557Sjimharris || ( 1632230557Sjimharris this_controller->port_agent.phy_ready_mask 1633230557Sjimharris != this_controller->port_agent.phy_configured_mask 1634230557Sjimharris ) 1635230557Sjimharris ) 1636230557Sjimharris { 1637230557Sjimharris return FALSE; 1638230557Sjimharris } 1639230557Sjimharris } 1640230557Sjimharris } 1641230557Sjimharris 1642230557Sjimharris return TRUE; 1643230557Sjimharris} 1644230557Sjimharris 1645230557Sjimharris/** 1646230557Sjimharris * @brief This method is called internally by the controller object to 1647230557Sjimharris * start the next phy on the controller. If all the phys have 1648230557Sjimharris * been starte, then this method will attempt to transition the 1649230557Sjimharris * controller to the READY state and inform the user 1650230557Sjimharris * (scic_cb_controller_start_complete()). 1651230557Sjimharris * 1652230557Sjimharris * @param[in] this_controller This parameter specifies the controller 1653230557Sjimharris * object for which to start the next phy. 1654230557Sjimharris * 1655230557Sjimharris * @return SCI_STATUS 1656230557Sjimharris */ 1657230557SjimharrisSCI_STATUS scic_sds_controller_start_next_phy( 1658230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 1659230557Sjimharris) 1660230557Sjimharris{ 1661230557Sjimharris SCI_STATUS status; 1662230557Sjimharris 1663230557Sjimharris status = SCI_SUCCESS; 1664230557Sjimharris 1665230557Sjimharris if (this_controller->phy_startup_timer_pending == FALSE) 1666230557Sjimharris { 1667230557Sjimharris if (this_controller->next_phy_to_start == SCI_MAX_PHYS) 1668230557Sjimharris { 1669230557Sjimharris // The controller has successfully finished the start process. 1670230557Sjimharris // Inform the SCI Core user and transition to the READY state. 1671230557Sjimharris if (scic_sds_controller_is_start_complete(this_controller) == TRUE) 1672230557Sjimharris { 1673230557Sjimharris scic_sds_controller_transition_to_ready( 1674230557Sjimharris this_controller, SCI_SUCCESS 1675230557Sjimharris ); 1676230557Sjimharris } 1677230557Sjimharris } 1678230557Sjimharris else 1679230557Sjimharris { 1680230557Sjimharris SCIC_SDS_PHY_T * the_phy; 1681230557Sjimharris 1682230557Sjimharris the_phy = &this_controller->phy_table[this_controller->next_phy_to_start]; 1683230557Sjimharris 1684230557Sjimharris if ( 1685230557Sjimharris this_controller->oem_parameters.sds1.controller.mode_type 1686230557Sjimharris == SCIC_PORT_MANUAL_CONFIGURATION_MODE 1687230557Sjimharris ) 1688230557Sjimharris { 1689230557Sjimharris if (scic_sds_phy_get_port(the_phy) == SCI_INVALID_HANDLE) 1690230557Sjimharris { 1691230557Sjimharris this_controller->next_phy_to_start++; 1692230557Sjimharris 1693230557Sjimharris // Caution recursion ahead be forwarned 1694230557Sjimharris // 1695230557Sjimharris // The PHY was never added to a PORT in MPC mode so start the next phy in sequence 1696230557Sjimharris // This phy will never go link up and will not draw power the OEM parameters either 1697230557Sjimharris // configured the phy incorrectly for the PORT or it was never assigned to a PORT 1698230557Sjimharris return scic_sds_controller_start_next_phy(this_controller); 1699230557Sjimharris } 1700230557Sjimharris } 1701230557Sjimharris 1702230557Sjimharris status = scic_phy_start(the_phy); 1703230557Sjimharris 1704230557Sjimharris if (status == SCI_SUCCESS) 1705230557Sjimharris { 1706230557Sjimharris scic_sds_controller_phy_timer_start(this_controller); 1707230557Sjimharris } 1708230557Sjimharris else 1709230557Sjimharris { 1710230557Sjimharris SCIC_LOG_WARNING(( 1711230557Sjimharris sci_base_object_get_logger(this_controller), 1712230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_PHY, 1713230557Sjimharris "Controller stop operation failed to stop phy %d because of status %d.\n", 1714230557Sjimharris this_controller->phy_table[this_controller->next_phy_to_start].phy_index, 1715230557Sjimharris status 1716230557Sjimharris )); 1717230557Sjimharris } 1718230557Sjimharris 1719230557Sjimharris this_controller->next_phy_to_start++; 1720230557Sjimharris } 1721230557Sjimharris } 1722230557Sjimharris 1723230557Sjimharris return status; 1724230557Sjimharris} 1725230557Sjimharris 1726230557Sjimharris/** 1727230557Sjimharris * @brief 1728230557Sjimharris * 1729230557Sjimharris * @param[in] this_controller 1730230557Sjimharris * 1731230557Sjimharris * @return SCI_STATUS 1732230557Sjimharris */ 1733230557SjimharrisSCI_STATUS scic_sds_controller_stop_phys( 1734230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 1735230557Sjimharris) 1736230557Sjimharris{ 1737230557Sjimharris U32 index; 1738230557Sjimharris SCI_STATUS status; 1739230557Sjimharris SCI_STATUS phy_status; 1740230557Sjimharris 1741230557Sjimharris status = SCI_SUCCESS; 1742230557Sjimharris 1743230557Sjimharris for (index = 0; index < SCI_MAX_PHYS; index++) 1744230557Sjimharris { 1745230557Sjimharris phy_status = scic_phy_stop(&this_controller->phy_table[index]); 1746230557Sjimharris 1747230557Sjimharris if ( 1748230557Sjimharris (phy_status != SCI_SUCCESS) 1749230557Sjimharris && (phy_status != SCI_FAILURE_INVALID_STATE) 1750230557Sjimharris ) 1751230557Sjimharris { 1752230557Sjimharris status = SCI_FAILURE; 1753230557Sjimharris 1754230557Sjimharris SCIC_LOG_WARNING(( 1755230557Sjimharris sci_base_object_get_logger(this_controller), 1756230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_PHY, 1757230557Sjimharris "Controller stop operation failed to stop phy %d because of status %d.\n", 1758230557Sjimharris this_controller->phy_table[index].phy_index, phy_status 1759230557Sjimharris )); 1760230557Sjimharris } 1761230557Sjimharris } 1762230557Sjimharris 1763230557Sjimharris return status; 1764230557Sjimharris} 1765230557Sjimharris 1766230557Sjimharris/** 1767230557Sjimharris * @brief 1768230557Sjimharris * 1769230557Sjimharris * @param[in] this_controller 1770230557Sjimharris * 1771230557Sjimharris * @return SCI_STATUS 1772230557Sjimharris */ 1773230557SjimharrisSCI_STATUS scic_sds_controller_stop_devices( 1774230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 1775230557Sjimharris) 1776230557Sjimharris{ 1777230557Sjimharris U32 index; 1778230557Sjimharris SCI_STATUS status; 1779230557Sjimharris SCI_STATUS device_status; 1780230557Sjimharris 1781230557Sjimharris status = SCI_SUCCESS; 1782230557Sjimharris 1783230557Sjimharris for (index = 0; index < this_controller->remote_node_entries; index++) 1784230557Sjimharris { 1785230557Sjimharris if (this_controller->device_table[index] != SCI_INVALID_HANDLE) 1786230557Sjimharris { 1787230557Sjimharris /// @todo What timeout value do we want to provide to this request? 1788230557Sjimharris device_status = scic_remote_device_stop(this_controller->device_table[index], 0); 1789230557Sjimharris 1790230557Sjimharris if ( 1791230557Sjimharris (device_status != SCI_SUCCESS) 1792230557Sjimharris && (device_status != SCI_FAILURE_INVALID_STATE) 1793230557Sjimharris ) 1794230557Sjimharris { 1795230557Sjimharris SCIC_LOG_WARNING(( 1796230557Sjimharris sci_base_object_get_logger(this_controller), 1797230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_SSP_REMOTE_TARGET, 1798230557Sjimharris "Controller stop operation failed to stop device 0x%x because of status %d.\n", 1799230557Sjimharris this_controller->device_table[index], device_status 1800230557Sjimharris )); 1801230557Sjimharris } 1802230557Sjimharris } 1803230557Sjimharris } 1804230557Sjimharris 1805230557Sjimharris return status; 1806230557Sjimharris} 1807230557Sjimharris 1808230557Sjimharris//****************************************************************************- 1809230557Sjimharris//* SCIC SDS Controller Power Control (Staggered Spinup) 1810230557Sjimharris//****************************************************************************- 1811230557Sjimharris 1812230557Sjimharris/** 1813230557Sjimharris * This method starts the power control timer for this controller object. 1814230557Sjimharris * 1815230557Sjimharris * @param this_controller 1816230557Sjimharris */ 1817230557Sjimharrisstatic 1818230557Sjimharrisvoid scic_sds_controller_power_control_timer_start( 1819230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 1820230557Sjimharris) 1821230557Sjimharris{ 1822230557Sjimharris scic_cb_timer_start( 1823230557Sjimharris this_controller, this_controller->power_control.timer, 1824230557Sjimharris SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL 1825230557Sjimharris ); 1826230557Sjimharris 1827230557Sjimharris this_controller->power_control.timer_started = TRUE; 1828230557Sjimharris} 1829230557Sjimharris 1830230557Sjimharris/** 1831230557Sjimharris * This method stops the power control timer for this controller object. 1832230557Sjimharris * 1833230557Sjimharris * @param this_controller 1834230557Sjimharris */ 1835230557Sjimharrisstatic 1836230557Sjimharrisvoid scic_sds_controller_power_control_timer_stop( 1837230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 1838230557Sjimharris) 1839230557Sjimharris{ 1840230557Sjimharris if (this_controller->power_control.timer_started) 1841230557Sjimharris { 1842230557Sjimharris scic_cb_timer_stop( 1843230557Sjimharris this_controller, this_controller->power_control.timer 1844230557Sjimharris ); 1845230557Sjimharris 1846230557Sjimharris this_controller->power_control.timer_started = FALSE; 1847230557Sjimharris } 1848230557Sjimharris} 1849230557Sjimharris 1850230557Sjimharris/** 1851230557Sjimharris * This method stops and starts the power control timer for this controller object. 1852230557Sjimharris * 1853230557Sjimharris * @param this_controller 1854230557Sjimharris */ 1855230557Sjimharrisstatic 1856230557Sjimharrisvoid scic_sds_controller_power_control_timer_restart( 1857230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 1858230557Sjimharris) 1859230557Sjimharris{ 1860230557Sjimharris scic_sds_controller_power_control_timer_stop(this_controller); 1861230557Sjimharris scic_sds_controller_power_control_timer_start(this_controller); 1862230557Sjimharris} 1863230557Sjimharris 1864230557Sjimharris 1865230557Sjimharris/** 1866230557Sjimharris * @brief 1867230557Sjimharris * 1868230557Sjimharris * @param[in] controller 1869230557Sjimharris */ 1870230557Sjimharrisvoid scic_sds_controller_power_control_timer_handler( 1871230557Sjimharris void *controller 1872230557Sjimharris) 1873230557Sjimharris{ 1874230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 1875230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 1876230557Sjimharris 1877230557Sjimharris this_controller->power_control.remote_devices_granted_power = 0; 1878230557Sjimharris 1879230557Sjimharris if (this_controller->power_control.phys_waiting == 0) 1880230557Sjimharris { 1881230557Sjimharris this_controller->power_control.timer_started = FALSE; 1882230557Sjimharris } 1883230557Sjimharris else 1884230557Sjimharris { 1885230557Sjimharris SCIC_SDS_PHY_T *the_phy = NULL; 1886230557Sjimharris U8 i; 1887230557Sjimharris 1888230557Sjimharris for (i=0; 1889230557Sjimharris (i < SCI_MAX_PHYS) 1890230557Sjimharris && (this_controller->power_control.phys_waiting != 0); 1891230557Sjimharris i++) 1892230557Sjimharris { 1893230557Sjimharris if (this_controller->power_control.requesters[i] != NULL) 1894230557Sjimharris { 1895230557Sjimharris if ( this_controller->power_control.remote_devices_granted_power < 1896230557Sjimharris this_controller->oem_parameters.sds1.controller.max_number_concurrent_device_spin_up 1897230557Sjimharris ) 1898230557Sjimharris { 1899230557Sjimharris the_phy = this_controller->power_control.requesters[i]; 1900230557Sjimharris this_controller->power_control.requesters[i] = NULL; 1901230557Sjimharris this_controller->power_control.phys_waiting--; 1902230557Sjimharris this_controller->power_control.remote_devices_granted_power ++; 1903230557Sjimharris scic_sds_phy_consume_power_handler(the_phy); 1904230557Sjimharris 1905230557Sjimharris if (the_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) 1906230557Sjimharris { 1907230557Sjimharris U8 j; 1908230557Sjimharris SCIC_SDS_PHY_T * current_requester_phy; 1909230557Sjimharris 1910230557Sjimharris for (j = 0; j < SCI_MAX_PHYS; j++) 1911230557Sjimharris { 1912230557Sjimharris current_requester_phy = this_controller->power_control.requesters[j]; 1913230557Sjimharris 1914230557Sjimharris //Search the power_control queue to see if there are other phys attached to 1915230557Sjimharris //the same remote device. If found, take all of them out of await_sas_power state. 1916230557Sjimharris if (current_requester_phy != NULL && 1917230557Sjimharris current_requester_phy != the_phy && 1918230557Sjimharris current_requester_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high 1919230557Sjimharris == the_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high && 1920230557Sjimharris current_requester_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low 1921230557Sjimharris == the_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low) 1922230557Sjimharris { 1923230557Sjimharris this_controller->power_control.requesters[j] = NULL; 1924230557Sjimharris this_controller->power_control.phys_waiting--; 1925230557Sjimharris scic_sds_phy_consume_power_handler(current_requester_phy); 1926230557Sjimharris } 1927230557Sjimharris } 1928230557Sjimharris } 1929230557Sjimharris } 1930230557Sjimharris else 1931230557Sjimharris { 1932230557Sjimharris break; 1933230557Sjimharris } 1934230557Sjimharris } 1935230557Sjimharris } 1936230557Sjimharris 1937230557Sjimharris // It doesn't matter if the power list is empty, we need to start the 1938230557Sjimharris // timer in case another phy becomes ready. 1939230557Sjimharris scic_sds_controller_power_control_timer_start(this_controller); 1940230557Sjimharris } 1941230557Sjimharris} 1942230557Sjimharris 1943230557Sjimharris/** 1944230557Sjimharris * @brief This method inserts the phy in the stagger spinup control queue. 1945230557Sjimharris * 1946230557Sjimharris * @param[in] this_controller 1947230557Sjimharris * @param[in] the_phy 1948230557Sjimharris */ 1949230557Sjimharrisvoid scic_sds_controller_power_control_queue_insert( 1950230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 1951230557Sjimharris SCIC_SDS_PHY_T *the_phy 1952230557Sjimharris) 1953230557Sjimharris{ 1954230557Sjimharris ASSERT (the_phy != NULL); 1955230557Sjimharris 1956230557Sjimharris if( this_controller->power_control.remote_devices_granted_power < 1957230557Sjimharris this_controller->oem_parameters.sds1.controller.max_number_concurrent_device_spin_up 1958230557Sjimharris ) 1959230557Sjimharris { 1960230557Sjimharris this_controller->power_control.remote_devices_granted_power ++; 1961230557Sjimharris scic_sds_phy_consume_power_handler(the_phy); 1962230557Sjimharris 1963230557Sjimharris //stop and start the power_control timer. When the timer fires, the 1964230557Sjimharris //no_of_devices_granted_power will be set to 0 1965230557Sjimharris scic_sds_controller_power_control_timer_restart (this_controller); 1966230557Sjimharris } 1967230557Sjimharris else 1968230557Sjimharris { 1969230557Sjimharris //there are phys, attached to the same sas address as this phy, are already 1970230557Sjimharris //in READY state, this phy don't need wait. 1971230557Sjimharris U8 i; 1972230557Sjimharris SCIC_SDS_PHY_T * current_phy; 1973230557Sjimharris for(i = 0; i < SCI_MAX_PHYS; i++) 1974230557Sjimharris { 1975230557Sjimharris current_phy = &this_controller->phy_table[i]; 1976230557Sjimharris 1977230557Sjimharris if (current_phy->parent.state_machine.current_state_id == SCI_BASE_PHY_STATE_READY && 1978230557Sjimharris current_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS && 1979230557Sjimharris current_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high 1980230557Sjimharris == the_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high && 1981230557Sjimharris current_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low 1982230557Sjimharris == the_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low) 1983230557Sjimharris { 1984230557Sjimharris scic_sds_phy_consume_power_handler(the_phy); 1985230557Sjimharris break; 1986230557Sjimharris } 1987230557Sjimharris } 1988230557Sjimharris 1989230557Sjimharris if (i == SCI_MAX_PHYS) 1990230557Sjimharris { 1991230557Sjimharris //Add the phy in the waiting list 1992230557Sjimharris this_controller->power_control.requesters[the_phy->phy_index] = the_phy; 1993230557Sjimharris this_controller->power_control.phys_waiting++; 1994230557Sjimharris } 1995230557Sjimharris } 1996230557Sjimharris} 1997230557Sjimharris 1998230557Sjimharris/** 1999230557Sjimharris * @brief This method removes the phy from the stagger spinup control 2000230557Sjimharris * queue. 2001230557Sjimharris * 2002230557Sjimharris * @param[in] this_controller 2003230557Sjimharris * @param[in] the_phy 2004230557Sjimharris */ 2005230557Sjimharrisvoid scic_sds_controller_power_control_queue_remove( 2006230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 2007230557Sjimharris SCIC_SDS_PHY_T *the_phy 2008230557Sjimharris) 2009230557Sjimharris{ 2010230557Sjimharris ASSERT (the_phy != NULL); 2011230557Sjimharris 2012230557Sjimharris if (this_controller->power_control.requesters[the_phy->phy_index] != NULL) 2013230557Sjimharris { 2014230557Sjimharris this_controller->power_control.phys_waiting--; 2015230557Sjimharris } 2016230557Sjimharris 2017230557Sjimharris this_controller->power_control.requesters[the_phy->phy_index] = NULL; 2018230557Sjimharris} 2019230557Sjimharris 2020230557Sjimharris//****************************************************************************- 2021230557Sjimharris//* SCIC SDS Controller Completion Routines 2022230557Sjimharris//****************************************************************************- 2023230557Sjimharris 2024230557Sjimharris/** 2025230557Sjimharris * @brief This method returns a TRUE value if the completion queue has 2026230557Sjimharris * entries that can be processed 2027230557Sjimharris * 2028230557Sjimharris * @param[in] this_controller 2029230557Sjimharris * 2030230557Sjimharris * @return BOOL 2031230557Sjimharris * @retval TRUE if the completion queue has entries to process 2032230557Sjimharris * FALSE if the completion queue has no entries to process 2033230557Sjimharris */ 2034230557Sjimharrisstatic 2035230557SjimharrisBOOL scic_sds_controller_completion_queue_has_entries( 2036230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 2037230557Sjimharris) 2038230557Sjimharris{ 2039230557Sjimharris U32 get_value = this_controller->completion_queue_get; 2040230557Sjimharris U32 get_index = get_value & SMU_COMPLETION_QUEUE_GET_POINTER_MASK; 2041230557Sjimharris if ( 2042230557Sjimharris NORMALIZE_GET_POINTER_CYCLE_BIT(get_value) 2043230557Sjimharris == COMPLETION_QUEUE_CYCLE_BIT(this_controller->completion_queue[get_index]) 2044230557Sjimharris ) 2045230557Sjimharris { 2046230557Sjimharris return TRUE; 2047230557Sjimharris } 2048230557Sjimharris 2049230557Sjimharris return FALSE; 2050230557Sjimharris} 2051230557Sjimharris 2052230557Sjimharris// --------------------------------------------------------------------------- 2053230557Sjimharris 2054230557Sjimharris/** 2055230557Sjimharris * @brief This method processes a task completion notification. This is 2056230557Sjimharris * called from within the controller completion handler. 2057230557Sjimharris * 2058230557Sjimharris * @param[in] this_controller 2059230557Sjimharris * @param[in] completion_entry 2060230557Sjimharris * 2061230557Sjimharris * @return none 2062230557Sjimharris */ 2063230557Sjimharrisstatic 2064230557Sjimharrisvoid scic_sds_controller_task_completion( 2065230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 2066230557Sjimharris U32 completion_entry 2067230557Sjimharris) 2068230557Sjimharris{ 2069230557Sjimharris U32 index; 2070230557Sjimharris SCIC_SDS_REQUEST_T *io_request; 2071230557Sjimharris 2072230557Sjimharris index = SCU_GET_COMPLETION_INDEX(completion_entry); 2073230557Sjimharris io_request = this_controller->io_request_table[index]; 2074230557Sjimharris 2075230557Sjimharris // Make sure that we really want to process this IO request 2076230557Sjimharris if ( 2077230557Sjimharris (io_request != SCI_INVALID_HANDLE) 2078230557Sjimharris && (io_request->io_tag != SCI_CONTROLLER_INVALID_IO_TAG) 2079230557Sjimharris && ( 2080230557Sjimharris scic_sds_io_tag_get_sequence(io_request->io_tag) 2081230557Sjimharris == this_controller->io_request_sequence[index] 2082230557Sjimharris ) 2083230557Sjimharris ) 2084230557Sjimharris { 2085230557Sjimharris // Yep this is a valid io request pass it along to the io request handler 2086230557Sjimharris scic_sds_io_request_tc_completion(io_request, completion_entry); 2087230557Sjimharris } 2088230557Sjimharris} 2089230557Sjimharris 2090230557Sjimharris/** 2091230557Sjimharris * @brief This method processes an SDMA completion event. This is called 2092230557Sjimharris * from within the controller completion handler. 2093230557Sjimharris * 2094230557Sjimharris * @param[in] this_controller 2095230557Sjimharris * @param[in] completion_entry 2096230557Sjimharris * 2097230557Sjimharris * @return none 2098230557Sjimharris */ 2099230557Sjimharrisstatic 2100230557Sjimharrisvoid scic_sds_controller_sdma_completion( 2101230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 2102230557Sjimharris U32 completion_entry 2103230557Sjimharris) 2104230557Sjimharris{ 2105230557Sjimharris U32 index; 2106230557Sjimharris SCIC_SDS_REQUEST_T *io_request; 2107230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T *device; 2108230557Sjimharris 2109230557Sjimharris index = SCU_GET_COMPLETION_INDEX(completion_entry); 2110230557Sjimharris 2111230557Sjimharris switch (scu_get_command_request_type(completion_entry)) 2112230557Sjimharris { 2113230557Sjimharris case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC: 2114230557Sjimharris case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC: 2115230557Sjimharris io_request = this_controller->io_request_table[index]; 2116230557Sjimharris SCIC_LOG_ERROR(( 2117230557Sjimharris sci_base_object_get_logger(this_controller), 2118230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER 2119230557Sjimharris | SCIC_LOG_OBJECT_SMP_IO_REQUEST 2120230557Sjimharris | SCIC_LOG_OBJECT_SSP_IO_REQUEST 2121230557Sjimharris | SCIC_LOG_OBJECT_STP_IO_REQUEST, 2122230557Sjimharris "SCIC SDS Completion type SDMA %x for io request %x\n", 2123230557Sjimharris completion_entry, 2124230557Sjimharris io_request 2125230557Sjimharris )); 2126230557Sjimharris /// @todo For a post TC operation we need to fail the IO request 2127230557Sjimharris break; 2128230557Sjimharris 2129230557Sjimharris case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_RNC: 2130230557Sjimharris case SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC: 2131230557Sjimharris case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC: 2132230557Sjimharris device = this_controller->device_table[index]; 2133230557Sjimharris SCIC_LOG_ERROR(( 2134230557Sjimharris sci_base_object_get_logger(this_controller), 2135230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER 2136230557Sjimharris | SCIC_LOG_OBJECT_SSP_REMOTE_TARGET 2137230557Sjimharris | SCIC_LOG_OBJECT_SMP_REMOTE_TARGET 2138230557Sjimharris | SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 2139230557Sjimharris "SCIC SDS Completion type SDMA %x for remote device %x\n", 2140230557Sjimharris completion_entry, 2141230557Sjimharris device 2142230557Sjimharris )); 2143230557Sjimharris /// @todo For a port RNC operation we need to fail the device 2144230557Sjimharris break; 2145230557Sjimharris 2146230557Sjimharris default: 2147230557Sjimharris SCIC_LOG_ERROR(( 2148230557Sjimharris sci_base_object_get_logger(this_controller), 2149230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2150230557Sjimharris "SCIC SDS Completion unknown SDMA completion type %x\n", 2151230557Sjimharris completion_entry 2152230557Sjimharris )); 2153230557Sjimharris break; 2154230557Sjimharris } 2155230557Sjimharris 2156230557Sjimharris /// This is an unexpected completion type and is un-recoverable 2157230557Sjimharris /// Transition to the failed state and wait for a controller reset 2158230557Sjimharris sci_base_state_machine_change_state( 2159230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 2160230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED 2161230557Sjimharris ); 2162230557Sjimharris} 2163230557Sjimharris 2164230557Sjimharris/** 2165230557Sjimharris * This method processes an unsolicited frame message. This is called from 2166230557Sjimharris * within the controller completion handler. 2167230557Sjimharris * 2168230557Sjimharris * @param[in] this_controller 2169230557Sjimharris * @param[in] completion_entry 2170230557Sjimharris * 2171230557Sjimharris * @return none 2172230557Sjimharris */ 2173230557Sjimharrisstatic 2174230557Sjimharrisvoid scic_sds_controller_unsolicited_frame( 2175230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 2176230557Sjimharris U32 completion_entry 2177230557Sjimharris) 2178230557Sjimharris{ 2179230557Sjimharris U32 index; 2180230557Sjimharris U32 frame_index; 2181230557Sjimharris 2182230557Sjimharris SCU_UNSOLICITED_FRAME_HEADER_T * frame_header; 2183230557Sjimharris SCIC_SDS_PHY_T * phy; 2184230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * device; 2185230557Sjimharris 2186230557Sjimharris SCI_STATUS result = SCI_FAILURE; 2187230557Sjimharris 2188230557Sjimharris frame_index = SCU_GET_FRAME_INDEX(completion_entry); 2189230557Sjimharris 2190230557Sjimharris frame_header 2191230557Sjimharris = this_controller->uf_control.buffers.array[frame_index].header; 2192230557Sjimharris this_controller->uf_control.buffers.array[frame_index].state 2193230557Sjimharris = UNSOLICITED_FRAME_IN_USE; 2194230557Sjimharris 2195230557Sjimharris if (SCU_GET_FRAME_ERROR(completion_entry)) 2196230557Sjimharris { 2197230557Sjimharris /// @todo If the IAF frame or SIGNATURE FIS frame has an error will 2198230557Sjimharris /// this cause a problem? We expect the phy initialization will 2199230557Sjimharris /// fail if there is an error in the frame. 2200230557Sjimharris scic_sds_controller_release_frame(this_controller, frame_index); 2201230557Sjimharris return; 2202230557Sjimharris } 2203230557Sjimharris 2204230557Sjimharris if (frame_header->is_address_frame) 2205230557Sjimharris { 2206230557Sjimharris index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry); 2207230557Sjimharris phy = &this_controller->phy_table[index]; 2208230557Sjimharris if (phy != NULL) 2209230557Sjimharris { 2210230557Sjimharris result = scic_sds_phy_frame_handler(phy, frame_index); 2211230557Sjimharris } 2212230557Sjimharris } 2213230557Sjimharris else 2214230557Sjimharris { 2215230557Sjimharris 2216230557Sjimharris index = SCU_GET_COMPLETION_INDEX(completion_entry); 2217230557Sjimharris 2218230557Sjimharris if (index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) 2219230557Sjimharris { 2220230557Sjimharris // This is a signature fis or a frame from a direct attached SATA 2221230557Sjimharris // device that has not yet been created. In either case forwared 2222230557Sjimharris // the frame to the PE and let it take care of the frame data. 2223230557Sjimharris index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry); 2224230557Sjimharris phy = &this_controller->phy_table[index]; 2225230557Sjimharris result = scic_sds_phy_frame_handler(phy, frame_index); 2226230557Sjimharris } 2227230557Sjimharris else 2228230557Sjimharris { 2229230557Sjimharris if (index < this_controller->remote_node_entries) 2230230557Sjimharris device = this_controller->device_table[index]; 2231230557Sjimharris else 2232230557Sjimharris device = NULL; 2233230557Sjimharris 2234230557Sjimharris if (device != NULL) 2235230557Sjimharris result = scic_sds_remote_device_frame_handler(device, frame_index); 2236230557Sjimharris else 2237230557Sjimharris scic_sds_controller_release_frame(this_controller, frame_index); 2238230557Sjimharris } 2239230557Sjimharris } 2240230557Sjimharris 2241230557Sjimharris if (result != SCI_SUCCESS) 2242230557Sjimharris { 2243230557Sjimharris /// @todo Is there any reason to report some additional error message 2244230557Sjimharris /// when we get this failure notifiction? 2245230557Sjimharris } 2246230557Sjimharris} 2247230557Sjimharris 2248230557Sjimharris/** 2249230557Sjimharris * @brief This method processes an event completion entry. This is called 2250230557Sjimharris * from within the controller completion handler. 2251230557Sjimharris * 2252230557Sjimharris * @param[in] this_controller 2253230557Sjimharris * @param[in] completion_entry 2254230557Sjimharris * 2255230557Sjimharris * @return none 2256230557Sjimharris */ 2257230557Sjimharrisstatic 2258230557Sjimharrisvoid scic_sds_controller_event_completion( 2259230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 2260230557Sjimharris U32 completion_entry 2261230557Sjimharris) 2262230557Sjimharris{ 2263230557Sjimharris U32 index; 2264230557Sjimharris SCIC_SDS_REQUEST_T *io_request; 2265230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T *device; 2266230557Sjimharris SCIC_SDS_PHY_T *phy; 2267230557Sjimharris 2268230557Sjimharris index = SCU_GET_COMPLETION_INDEX(completion_entry); 2269230557Sjimharris 2270230557Sjimharris switch (scu_get_event_type(completion_entry)) 2271230557Sjimharris { 2272230557Sjimharris case SCU_EVENT_TYPE_SMU_COMMAND_ERROR: 2273230557Sjimharris /// @todo The driver did something wrong and we need to fix the condtion. 2274230557Sjimharris SCIC_LOG_ERROR(( 2275230557Sjimharris sci_base_object_get_logger(this_controller), 2276230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2277230557Sjimharris "SCIC Controller 0x%x received SMU command error 0x%x\n", 2278230557Sjimharris this_controller, completion_entry 2279230557Sjimharris )); 2280230557Sjimharris break; 2281230557Sjimharris 2282230557Sjimharris case SCU_EVENT_TYPE_FATAL_MEMORY_ERROR: 2283230557Sjimharris // report fatal memory error 2284230557Sjimharris this_controller->parent.error = SCI_CONTROLLER_FATAL_MEMORY_ERROR; 2285230557Sjimharris 2286230557Sjimharris sci_base_state_machine_change_state( 2287230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 2288230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED 2289230557Sjimharris ); 2290230557Sjimharris 2291230557Sjimharris //continue as in following events 2292230557Sjimharris case SCU_EVENT_TYPE_SMU_PCQ_ERROR: 2293230557Sjimharris case SCU_EVENT_TYPE_SMU_ERROR: 2294230557Sjimharris SCIC_LOG_ERROR(( 2295230557Sjimharris sci_base_object_get_logger(this_controller), 2296230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2297230557Sjimharris "SCIC Controller 0x%x received fatal controller event 0x%x\n", 2298230557Sjimharris this_controller, completion_entry 2299230557Sjimharris )); 2300230557Sjimharris break; 2301230557Sjimharris 2302230557Sjimharris case SCU_EVENT_TYPE_TRANSPORT_ERROR: 2303230557Sjimharris io_request = this_controller->io_request_table[index]; 2304230557Sjimharris scic_sds_io_request_event_handler(io_request, completion_entry); 2305230557Sjimharris break; 2306230557Sjimharris 2307230557Sjimharris case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT: 2308230557Sjimharris switch (scu_get_event_specifier(completion_entry)) 2309230557Sjimharris { 2310230557Sjimharris case SCU_EVENT_SPECIFIC_SMP_RESPONSE_NO_PE: 2311230557Sjimharris case SCU_EVENT_SPECIFIC_TASK_TIMEOUT: 2312230557Sjimharris io_request = this_controller->io_request_table[index]; 2313230557Sjimharris if (io_request != SCI_INVALID_HANDLE) 2314230557Sjimharris { 2315230557Sjimharris scic_sds_io_request_event_handler(io_request, completion_entry); 2316230557Sjimharris } 2317230557Sjimharris else 2318230557Sjimharris { 2319230557Sjimharris SCIC_LOG_WARNING(( 2320230557Sjimharris sci_base_object_get_logger(this_controller), 2321230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | 2322230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST | 2323230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST | 2324230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST, 2325230557Sjimharris "SCIC Controller 0x%x received event 0x%x for io request object that doesnt exist.\n", 2326230557Sjimharris this_controller, completion_entry 2327230557Sjimharris )); 2328230557Sjimharris } 2329230557Sjimharris break; 2330230557Sjimharris 2331230557Sjimharris case SCU_EVENT_SPECIFIC_IT_NEXUS_TIMEOUT: 2332230557Sjimharris device = this_controller->device_table[index]; 2333230557Sjimharris if (device != SCI_INVALID_HANDLE) 2334230557Sjimharris { 2335230557Sjimharris scic_sds_remote_device_event_handler(device, completion_entry); 2336230557Sjimharris } 2337230557Sjimharris else 2338230557Sjimharris { 2339230557Sjimharris SCIC_LOG_WARNING(( 2340230557Sjimharris sci_base_object_get_logger(this_controller), 2341230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | 2342230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 2343230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 2344230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 2345230557Sjimharris "SCIC Controller 0x%x received event 0x%x for remote device object that doesnt exist.\n", 2346230557Sjimharris this_controller, completion_entry 2347230557Sjimharris )); 2348230557Sjimharris } 2349230557Sjimharris break; 2350230557Sjimharris } 2351230557Sjimharris break; 2352230557Sjimharris 2353230557Sjimharris case SCU_EVENT_TYPE_BROADCAST_CHANGE: 2354230557Sjimharris // direct the broadcast change event to the phy first and then let 2355230557Sjimharris // the phy redirect the broadcast change to the port object 2356230557Sjimharris case SCU_EVENT_TYPE_ERR_CNT_EVENT: 2357230557Sjimharris // direct error counter event to the phy object since that is where 2358230557Sjimharris // we get the event notification. This is a type 4 event. 2359230557Sjimharris case SCU_EVENT_TYPE_OSSP_EVENT: 2360230557Sjimharris index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry); 2361230557Sjimharris phy = &this_controller->phy_table[index]; 2362230557Sjimharris scic_sds_phy_event_handler(phy, completion_entry); 2363230557Sjimharris break; 2364230557Sjimharris 2365230557Sjimharris case SCU_EVENT_TYPE_RNC_SUSPEND_TX: 2366230557Sjimharris case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: 2367230557Sjimharris case SCU_EVENT_TYPE_RNC_OPS_MISC: 2368230557Sjimharris if (index < this_controller->remote_node_entries) 2369230557Sjimharris { 2370230557Sjimharris device = this_controller->device_table[index]; 2371230557Sjimharris 2372230557Sjimharris if (device != NULL) 2373230557Sjimharris { 2374230557Sjimharris scic_sds_remote_device_event_handler(device, completion_entry); 2375230557Sjimharris } 2376230557Sjimharris } 2377230557Sjimharris else 2378230557Sjimharris { 2379230557Sjimharris SCIC_LOG_ERROR(( 2380230557Sjimharris sci_base_object_get_logger(this_controller), 2381230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | 2382230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 2383230557Sjimharris SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 2384230557Sjimharris SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 2385230557Sjimharris "SCIC Controller 0x%x received event 0x%x for remote device object 0x%0x that doesnt exist.\n", 2386230557Sjimharris this_controller, completion_entry, index 2387230557Sjimharris )); 2388230557Sjimharris } 2389230557Sjimharris break; 2390230557Sjimharris 2391230557Sjimharris default: 2392230557Sjimharris SCIC_LOG_WARNING(( 2393230557Sjimharris sci_base_object_get_logger(this_controller), 2394230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2395230557Sjimharris "SCIC Controller received unknown event code %x\n", 2396230557Sjimharris completion_entry 2397230557Sjimharris )); 2398230557Sjimharris break; 2399230557Sjimharris } 2400230557Sjimharris} 2401230557Sjimharris 2402230557Sjimharris/** 2403230557Sjimharris * @brief This method is a private routine for processing the completion 2404230557Sjimharris * queue entries. 2405230557Sjimharris * 2406230557Sjimharris * @param[in] this_controller 2407230557Sjimharris * 2408230557Sjimharris * @return none 2409230557Sjimharris */ 2410230557Sjimharrisstatic 2411230557Sjimharrisvoid scic_sds_controller_process_completions( 2412230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 2413230557Sjimharris) 2414230557Sjimharris{ 2415230557Sjimharris U32 completion_count = 0; 2416230557Sjimharris U32 completion_entry; 2417230557Sjimharris U32 get_index; 2418230557Sjimharris U32 get_cycle; 2419230557Sjimharris U32 event_index; 2420230557Sjimharris U32 event_cycle; 2421230557Sjimharris 2422230557Sjimharris SCIC_LOG_TRACE(( 2423230557Sjimharris sci_base_object_get_logger(this_controller), 2424230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2425230557Sjimharris "scic_sds_controller_process_completions(0x%x) enter\n", 2426230557Sjimharris this_controller 2427230557Sjimharris )); 2428230557Sjimharris 2429230557Sjimharris SCIC_LOG_TRACE(( 2430230557Sjimharris sci_base_object_get_logger(this_controller), 2431230557Sjimharris SCIC_LOG_OBJECT_COMPLETION_QUEUE, 2432230557Sjimharris "completion queue begining get : 0x%08x\n", 2433230557Sjimharris this_controller->completion_queue_get 2434230557Sjimharris )); 2435230557Sjimharris 2436230557Sjimharris // Get the component parts of the completion queue 2437230557Sjimharris get_index = NORMALIZE_GET_POINTER(this_controller->completion_queue_get); 2438230557Sjimharris get_cycle = SMU_CQGR_CYCLE_BIT & this_controller->completion_queue_get; 2439230557Sjimharris 2440230557Sjimharris event_index = NORMALIZE_EVENT_POINTER(this_controller->completion_queue_get); 2441230557Sjimharris event_cycle = SMU_CQGR_EVENT_CYCLE_BIT & this_controller->completion_queue_get; 2442230557Sjimharris 2443230557Sjimharris while ( 2444230557Sjimharris NORMALIZE_GET_POINTER_CYCLE_BIT(get_cycle) 2445230557Sjimharris == COMPLETION_QUEUE_CYCLE_BIT(this_controller->completion_queue[get_index]) 2446230557Sjimharris ) 2447230557Sjimharris { 2448230557Sjimharris completion_count++; 2449230557Sjimharris 2450230557Sjimharris completion_entry = this_controller->completion_queue[get_index]; 2451230557Sjimharris INCREMENT_COMPLETION_QUEUE_GET(this_controller, get_index, get_cycle); 2452230557Sjimharris 2453230557Sjimharris SCIC_LOG_TRACE(( 2454230557Sjimharris sci_base_object_get_logger(this_controller), 2455230557Sjimharris SCIC_LOG_OBJECT_COMPLETION_QUEUE, 2456230557Sjimharris "completion queue entry : 0x%08x\n", 2457230557Sjimharris completion_entry 2458230557Sjimharris )); 2459230557Sjimharris 2460230557Sjimharris switch (SCU_GET_COMPLETION_TYPE(completion_entry)) 2461230557Sjimharris { 2462230557Sjimharris case SCU_COMPLETION_TYPE_TASK: 2463230557Sjimharris scic_sds_controller_task_completion(this_controller, completion_entry); 2464230557Sjimharris break; 2465230557Sjimharris 2466230557Sjimharris case SCU_COMPLETION_TYPE_SDMA: 2467230557Sjimharris scic_sds_controller_sdma_completion(this_controller, completion_entry); 2468230557Sjimharris break; 2469230557Sjimharris 2470230557Sjimharris case SCU_COMPLETION_TYPE_UFI: 2471230557Sjimharris scic_sds_controller_unsolicited_frame(this_controller, completion_entry); 2472230557Sjimharris break; 2473230557Sjimharris 2474230557Sjimharris case SCU_COMPLETION_TYPE_EVENT: 2475230557Sjimharris scic_sds_controller_event_completion(this_controller, completion_entry); 2476230557Sjimharris break; 2477230557Sjimharris 2478230557Sjimharris case SCU_COMPLETION_TYPE_NOTIFY: 2479230557Sjimharris // Presently we do the same thing with a notify event that we do with the 2480230557Sjimharris // other event codes. 2481230557Sjimharris INCREMENT_EVENT_QUEUE_GET(this_controller, event_index, event_cycle); 2482230557Sjimharris scic_sds_controller_event_completion(this_controller, completion_entry); 2483230557Sjimharris break; 2484230557Sjimharris 2485230557Sjimharris default: 2486230557Sjimharris SCIC_LOG_WARNING(( 2487230557Sjimharris sci_base_object_get_logger(this_controller), 2488230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2489230557Sjimharris "SCIC Controller received unknown completion type %x\n", 2490230557Sjimharris completion_entry 2491230557Sjimharris )); 2492230557Sjimharris break; 2493230557Sjimharris } 2494230557Sjimharris } 2495230557Sjimharris 2496230557Sjimharris // Update the get register if we completed one or more entries 2497230557Sjimharris if (completion_count > 0) 2498230557Sjimharris { 2499230557Sjimharris this_controller->completion_queue_get = 2500230557Sjimharris SMU_CQGR_GEN_BIT(ENABLE) 2501230557Sjimharris | SMU_CQGR_GEN_BIT(EVENT_ENABLE) 2502230557Sjimharris | event_cycle | SMU_CQGR_GEN_VAL(EVENT_POINTER, event_index) 2503230557Sjimharris | get_cycle | SMU_CQGR_GEN_VAL(POINTER, get_index) ; 2504230557Sjimharris 2505230557Sjimharris SMU_CQGR_WRITE(this_controller, this_controller->completion_queue_get); 2506230557Sjimharris } 2507230557Sjimharris 2508230557Sjimharris SCIC_LOG_TRACE(( 2509230557Sjimharris sci_base_object_get_logger(this_controller), 2510230557Sjimharris SCIC_LOG_OBJECT_COMPLETION_QUEUE, 2511230557Sjimharris "completion queue ending get : 0x%08x\n", 2512230557Sjimharris this_controller->completion_queue_get 2513230557Sjimharris )); 2514230557Sjimharris 2515230557Sjimharris} 2516230557Sjimharris 2517230557Sjimharris/** 2518230557Sjimharris * @brief This method is a private routine for processing the completion 2519230557Sjimharris * queue entries. 2520230557Sjimharris * 2521230557Sjimharris * @param[in] this_controller 2522230557Sjimharris * 2523230557Sjimharris * @return none 2524230557Sjimharris */ 2525230557Sjimharrisstatic 2526230557Sjimharrisvoid scic_sds_controller_transitioned_process_completions( 2527230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller 2528230557Sjimharris) 2529230557Sjimharris{ 2530230557Sjimharris U32 completion_count = 0; 2531230557Sjimharris U32 completion_entry; 2532230557Sjimharris U32 get_index; 2533230557Sjimharris U32 get_cycle; 2534230557Sjimharris U32 event_index; 2535230557Sjimharris U32 event_cycle; 2536230557Sjimharris 2537230557Sjimharris SCIC_LOG_TRACE(( 2538230557Sjimharris sci_base_object_get_logger(this_controller), 2539230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2540230557Sjimharris "scic_sds_controller_transitioned_process_completions(0x%x) enter\n", 2541230557Sjimharris this_controller 2542230557Sjimharris )); 2543230557Sjimharris 2544230557Sjimharris SCIC_LOG_TRACE(( 2545230557Sjimharris sci_base_object_get_logger(this_controller), 2546230557Sjimharris SCIC_LOG_OBJECT_COMPLETION_QUEUE, 2547230557Sjimharris "completion queue begining get : 0x%08x\n", 2548230557Sjimharris this_controller->completion_queue_get 2549230557Sjimharris )); 2550230557Sjimharris 2551230557Sjimharris // Get the component parts of the completion queue 2552230557Sjimharris get_index = NORMALIZE_GET_POINTER(this_controller->completion_queue_get); 2553230557Sjimharris get_cycle = SMU_CQGR_CYCLE_BIT & this_controller->completion_queue_get; 2554230557Sjimharris 2555230557Sjimharris event_index = NORMALIZE_EVENT_POINTER(this_controller->completion_queue_get); 2556230557Sjimharris event_cycle = SMU_CQGR_EVENT_CYCLE_BIT & this_controller->completion_queue_get; 2557230557Sjimharris 2558230557Sjimharris while ( 2559230557Sjimharris NORMALIZE_GET_POINTER_CYCLE_BIT(get_cycle) 2560230557Sjimharris == COMPLETION_QUEUE_CYCLE_BIT( 2561230557Sjimharris this_controller->completion_queue[get_index]) 2562230557Sjimharris ) 2563230557Sjimharris { 2564230557Sjimharris completion_count++; 2565230557Sjimharris 2566230557Sjimharris completion_entry = this_controller->completion_queue[get_index]; 2567230557Sjimharris INCREMENT_COMPLETION_QUEUE_GET(this_controller, get_index, get_cycle); 2568230557Sjimharris 2569230557Sjimharris SCIC_LOG_TRACE(( 2570230557Sjimharris sci_base_object_get_logger(this_controller), 2571230557Sjimharris SCIC_LOG_OBJECT_COMPLETION_QUEUE, 2572230557Sjimharris "completion queue entry : 0x%08x\n", 2573230557Sjimharris completion_entry 2574230557Sjimharris )); 2575230557Sjimharris 2576230557Sjimharris switch (SCU_GET_COMPLETION_TYPE(completion_entry)) 2577230557Sjimharris { 2578230557Sjimharris case SCU_COMPLETION_TYPE_TASK: 2579230557Sjimharris scic_sds_controller_task_completion(this_controller, completion_entry); 2580230557Sjimharris break; 2581230557Sjimharris 2582230557Sjimharris case SCU_COMPLETION_TYPE_NOTIFY: 2583230557Sjimharris INCREMENT_EVENT_QUEUE_GET(this_controller, event_index, event_cycle); 2584230557Sjimharris // Fall-through 2585230557Sjimharris 2586230557Sjimharris case SCU_COMPLETION_TYPE_EVENT: 2587230557Sjimharris case SCU_COMPLETION_TYPE_SDMA: 2588230557Sjimharris case SCU_COMPLETION_TYPE_UFI: 2589230557Sjimharris default: 2590230557Sjimharris SCIC_LOG_WARNING(( 2591230557Sjimharris sci_base_object_get_logger(this_controller), 2592230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2593230557Sjimharris "SCIC Controller ignoring completion type %x\n", 2594230557Sjimharris completion_entry 2595230557Sjimharris )); 2596230557Sjimharris break; 2597230557Sjimharris } 2598230557Sjimharris } 2599230557Sjimharris 2600230557Sjimharris // Update the get register if we completed one or more entries 2601230557Sjimharris if (completion_count > 0) 2602230557Sjimharris { 2603230557Sjimharris this_controller->completion_queue_get = 2604230557Sjimharris SMU_CQGR_GEN_BIT(ENABLE) 2605230557Sjimharris | SMU_CQGR_GEN_BIT(EVENT_ENABLE) 2606230557Sjimharris | event_cycle | SMU_CQGR_GEN_VAL(EVENT_POINTER, event_index) 2607230557Sjimharris | get_cycle | SMU_CQGR_GEN_VAL(POINTER, get_index) ; 2608230557Sjimharris 2609230557Sjimharris SMU_CQGR_WRITE(this_controller, this_controller->completion_queue_get); 2610230557Sjimharris } 2611230557Sjimharris 2612230557Sjimharris SCIC_LOG_TRACE(( 2613230557Sjimharris sci_base_object_get_logger(this_controller), 2614230557Sjimharris SCIC_LOG_OBJECT_COMPLETION_QUEUE, 2615230557Sjimharris "completion queue ending get : 0x%08x\n", 2616230557Sjimharris this_controller->completion_queue_get 2617230557Sjimharris )); 2618230557Sjimharris} 2619230557Sjimharris 2620230557Sjimharris//****************************************************************************- 2621230557Sjimharris//* SCIC SDS Controller Interrupt and Completion functions 2622230557Sjimharris//****************************************************************************- 2623230557Sjimharris 2624230557Sjimharris/** 2625230557Sjimharris * @brief This method provides standard (common) processing of interrupts 2626230557Sjimharris * for polling and legacy based interrupts. 2627230557Sjimharris * 2628230557Sjimharris * @param[in] controller 2629230557Sjimharris * @param[in] interrupt_status 2630230557Sjimharris * 2631230557Sjimharris * @return This method returns a boolean (BOOL) indication as to 2632230557Sjimharris * whether an completions are pending to be processed. 2633230557Sjimharris * @retval TRUE if an interrupt is to be processed 2634230557Sjimharris * @retval FALSE if no interrupt was pending 2635230557Sjimharris */ 2636230557Sjimharrisstatic 2637230557SjimharrisBOOL scic_sds_controller_standard_interrupt_handler( 2638230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 2639230557Sjimharris U32 interrupt_status 2640230557Sjimharris) 2641230557Sjimharris{ 2642230557Sjimharris BOOL is_completion_needed = FALSE; 2643230557Sjimharris 2644230557Sjimharris SCIC_LOG_TRACE(( 2645230557Sjimharris sci_base_object_get_logger(this_controller), 2646230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2647230557Sjimharris "scic_sds_controller_standard_interrupt_handler(0x%d,0x%d) enter\n", 2648230557Sjimharris this_controller, interrupt_status 2649230557Sjimharris )); 2650230557Sjimharris 2651230557Sjimharris if ( 2652230557Sjimharris (interrupt_status & SMU_ISR_QUEUE_ERROR) 2653230557Sjimharris || ( 2654230557Sjimharris (interrupt_status & SMU_ISR_QUEUE_SUSPEND) 2655230557Sjimharris && (!scic_sds_controller_completion_queue_has_entries(this_controller)) 2656230557Sjimharris ) 2657230557Sjimharris ) 2658230557Sjimharris { 2659230557Sjimharris // We have a fatal error on the read of the completion queue bar 2660230557Sjimharris // OR 2661230557Sjimharris // We have a fatal error there is nothing in the completion queue 2662230557Sjimharris // but we have a report from the hardware that the queue is full 2663230557Sjimharris /// @todo how do we request the a controller reset 2664230557Sjimharris is_completion_needed = TRUE; 2665230557Sjimharris this_controller->encountered_fatal_error = TRUE; 2666230557Sjimharris } 2667230557Sjimharris 2668230557Sjimharris if (scic_sds_controller_completion_queue_has_entries(this_controller)) 2669230557Sjimharris { 2670230557Sjimharris is_completion_needed = TRUE; 2671230557Sjimharris } 2672230557Sjimharris 2673230557Sjimharris return is_completion_needed; 2674230557Sjimharris} 2675230557Sjimharris 2676230557Sjimharris/** 2677230557Sjimharris * @brief This is the method provided to handle polling for interrupts 2678230557Sjimharris * for the controller object. 2679230557Sjimharris * 2680230557Sjimharris * @param[in] controller 2681230557Sjimharris * 2682230557Sjimharris * @return BOOL 2683230557Sjimharris * @retval TRUE if an interrupt is to be processed 2684230557Sjimharris * @retval FALSE if no interrupt was pending 2685230557Sjimharris */ 2686230557Sjimharrisstatic 2687230557SjimharrisBOOL scic_sds_controller_polling_interrupt_handler( 2688230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 2689230557Sjimharris) 2690230557Sjimharris{ 2691230557Sjimharris U32 interrupt_status; 2692230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 2693230557Sjimharris 2694230557Sjimharris SCIC_LOG_TRACE(( 2695230557Sjimharris sci_base_object_get_logger(controller), 2696230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2697230557Sjimharris "scic_sds_controller_polling_interrupt_handler(0x%d) enter\n", 2698230557Sjimharris controller 2699230557Sjimharris )); 2700230557Sjimharris 2701230557Sjimharris /* 2702230557Sjimharris * In INTERRUPT_POLLING_MODE we exit the interrupt handler if the hardware 2703230557Sjimharris * indicates nothing is pending. Since we are not being called from a real 2704230557Sjimharris * interrupt, we don't want to confuse the hardware by servicing the 2705230557Sjimharris * completion queue before the hardware indicates it is ready. We'll 2706230557Sjimharris * simply wait for another polling interval and check again. 2707230557Sjimharris */ 2708230557Sjimharris interrupt_status = SMU_ISR_READ(this_controller); 2709230557Sjimharris if ((interrupt_status & 2710230557Sjimharris (SMU_ISR_COMPLETION | 2711230557Sjimharris SMU_ISR_QUEUE_ERROR | 2712230557Sjimharris SMU_ISR_QUEUE_SUSPEND)) == 0) 2713230557Sjimharris { 2714230557Sjimharris return FALSE; 2715230557Sjimharris } 2716230557Sjimharris 2717230557Sjimharris return scic_sds_controller_standard_interrupt_handler( 2718230557Sjimharris controller, interrupt_status 2719230557Sjimharris ); 2720230557Sjimharris} 2721230557Sjimharris 2722230557Sjimharris/** 2723230557Sjimharris * @brief This is the method provided to handle completions when interrupt 2724230557Sjimharris * polling is in use. 2725230557Sjimharris * 2726230557Sjimharris * @param[in] controller 2727230557Sjimharris * 2728230557Sjimharris * @return none 2729230557Sjimharris */ 2730230557Sjimharrisstatic 2731230557Sjimharrisvoid scic_sds_controller_polling_completion_handler( 2732230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 2733230557Sjimharris) 2734230557Sjimharris{ 2735230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 2736230557Sjimharris 2737230557Sjimharris SCIC_LOG_TRACE(( 2738230557Sjimharris sci_base_object_get_logger(controller), 2739230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2740230557Sjimharris "scic_sds_controller_polling_completion_handler(0x%d) enter\n", 2741230557Sjimharris controller 2742230557Sjimharris )); 2743230557Sjimharris 2744230557Sjimharris if (this_controller->encountered_fatal_error == TRUE) 2745230557Sjimharris { 2746230557Sjimharris SCIC_LOG_ERROR(( 2747230557Sjimharris sci_base_object_get_logger(this_controller), 2748230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2749230557Sjimharris "SCIC Controller has encountered a fatal error.\n" 2750230557Sjimharris )); 2751230557Sjimharris 2752230557Sjimharris sci_base_state_machine_change_state( 2753230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 2754230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED 2755230557Sjimharris ); 2756230557Sjimharris } 2757230557Sjimharris else if (scic_sds_controller_completion_queue_has_entries(this_controller)) 2758230557Sjimharris { 2759230557Sjimharris if (this_controller->restrict_completions == FALSE) 2760230557Sjimharris scic_sds_controller_process_completions(this_controller); 2761230557Sjimharris else 2762230557Sjimharris scic_sds_controller_transitioned_process_completions(this_controller); 2763230557Sjimharris } 2764230557Sjimharris 2765230557Sjimharris /* 2766230557Sjimharris * The interrupt handler does not adjust the CQ's 2767230557Sjimharris * get pointer. So, SCU's INTx pin stays asserted during the 2768230557Sjimharris * interrupt handler even though it tries to clear the interrupt 2769230557Sjimharris * source. Therefore, the completion handler must ensure that the 2770230557Sjimharris * interrupt source is cleared. Otherwise, we get a spurious 2771230557Sjimharris * interrupt for which the interrupt handler will not issue a 2772230557Sjimharris * corresponding completion event. Also, we unmask interrupts. 2773230557Sjimharris */ 2774230557Sjimharris SMU_ISR_WRITE( 2775230557Sjimharris this_controller, 2776230557Sjimharris (U32)(SMU_ISR_COMPLETION | SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND) 2777230557Sjimharris ); 2778230557Sjimharris} 2779230557Sjimharris 2780230557Sjimharris#if !defined(DISABLE_INTERRUPTS) 2781230557Sjimharris/** 2782230557Sjimharris * @brief This is the method provided to handle legacy interrupts for the 2783230557Sjimharris * controller object. 2784230557Sjimharris * 2785230557Sjimharris * @param[in] controller 2786230557Sjimharris * 2787230557Sjimharris * @return BOOL 2788230557Sjimharris * @retval TRUE if an interrupt is processed 2789230557Sjimharris * FALSE if no interrupt was processed 2790230557Sjimharris */ 2791230557Sjimharrisstatic 2792230557SjimharrisBOOL scic_sds_controller_legacy_interrupt_handler( 2793230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 2794230557Sjimharris) 2795230557Sjimharris{ 2796230557Sjimharris U32 interrupt_status; 2797230557Sjimharris BOOL is_completion_needed; 2798230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 2799230557Sjimharris 2800230557Sjimharris interrupt_status = SMU_ISR_READ(this_controller); 2801230557Sjimharris is_completion_needed = scic_sds_controller_standard_interrupt_handler( 2802230557Sjimharris this_controller, interrupt_status 2803230557Sjimharris ); 2804230557Sjimharris 2805230557Sjimharris return is_completion_needed; 2806230557Sjimharris} 2807230557Sjimharris 2808230557Sjimharris 2809230557Sjimharris/** 2810230557Sjimharris * @brief This is the method provided to handle legacy completions it is 2811230557Sjimharris * expected that the SCI User will call this completion handler 2812230557Sjimharris * anytime the interrupt handler reports that it has handled an 2813230557Sjimharris * interrupt. 2814230557Sjimharris * 2815230557Sjimharris * @param[in] controller 2816230557Sjimharris * 2817230557Sjimharris * @return none 2818230557Sjimharris */ 2819230557Sjimharrisstatic 2820230557Sjimharrisvoid scic_sds_controller_legacy_completion_handler( 2821230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 2822230557Sjimharris) 2823230557Sjimharris{ 2824230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 2825230557Sjimharris 2826230557Sjimharris SCIC_LOG_TRACE(( 2827230557Sjimharris sci_base_object_get_logger(controller), 2828230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2829230557Sjimharris "scic_sds_controller_legacy_completion_handler(0x%d) enter\n", 2830230557Sjimharris controller 2831230557Sjimharris )); 2832230557Sjimharris 2833230557Sjimharris scic_sds_controller_polling_completion_handler(controller); 2834230557Sjimharris 2835230557Sjimharris SMU_IMR_WRITE(this_controller, 0x00000000); 2836230557Sjimharris 2837230557Sjimharris#ifdef IMR_READ_FENCE 2838230557Sjimharris { 2839230557Sjimharris volatile U32 int_mask_value = 0; 2840230557Sjimharris ULONG count = 0; 2841230557Sjimharris 2842230557Sjimharris /* 2843230557Sjimharris * Temporary code since we have seen with legacy interrupts 2844230557Sjimharris * that interrupts are still masked after clearing the mask 2845230557Sjimharris * above. This may be an Arlington problem or it may be an 2846230557Sjimharris * old driver problem. Presently this code is turned off 2847230557Sjimharris * since we have not seen this problem recently. 2848230557Sjimharris */ 2849230557Sjimharris do 2850230557Sjimharris { 2851230557Sjimharris int_mask_value = SMU_IMR_READ(this_controler); 2852230557Sjimharris 2853230557Sjimharris if (count++ > 10) 2854230557Sjimharris { 2855230557Sjimharris #ifdef ALLOW_ENTER_DEBUGGER 2856230557Sjimharris __debugbreak(); 2857230557Sjimharris #endif 2858230557Sjimharris break; 2859230557Sjimharris } 2860230557Sjimharris } while (int_mask_value != 0); 2861230557Sjimharris } 2862230557Sjimharris#endif 2863230557Sjimharris} 2864230557Sjimharris 2865230557Sjimharris/** 2866230557Sjimharris * @brief This is the method provided to handle an MSIX interrupt message 2867230557Sjimharris * when there is just a single MSIX message being provided by the 2868230557Sjimharris * hardware. This mode of operation is single vector mode. 2869230557Sjimharris * 2870230557Sjimharris * @param[in] controller 2871230557Sjimharris * 2872230557Sjimharris * @return BOOL 2873230557Sjimharris * @retval TRUE if an interrupt is processed 2874230557Sjimharris * FALSE if no interrupt was processed 2875230557Sjimharris */ 2876230557Sjimharrisstatic 2877230557SjimharrisBOOL scic_sds_controller_single_vector_interrupt_handler( 2878230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 2879230557Sjimharris) 2880230557Sjimharris{ 2881230557Sjimharris U32 interrupt_status; 2882230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 2883230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 2884230557Sjimharris 2885230557Sjimharris // Mask the interrupts 2886230557Sjimharris // There is a race in the hardware that could cause us not to be notified 2887230557Sjimharris // of an interrupt completion if we do not take this step. We will unmask 2888230557Sjimharris // the interrupts in the completion routine. 2889230557Sjimharris SMU_IMR_WRITE(this_controller, 0xFFFFFFFF); 2890230557Sjimharris 2891230557Sjimharris interrupt_status = SMU_ISR_READ(this_controller); 2892230557Sjimharris interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND); 2893230557Sjimharris 2894230557Sjimharris if ( 2895230557Sjimharris (interrupt_status == 0) 2896230557Sjimharris && scic_sds_controller_completion_queue_has_entries(this_controller) 2897230557Sjimharris ) 2898230557Sjimharris { 2899230557Sjimharris // There is at least one completion queue entry to process so we can 2900230557Sjimharris // return a success and ignore for now the case of an error interrupt 2901230557Sjimharris SMU_ISR_WRITE(this_controller, SMU_ISR_COMPLETION); 2902230557Sjimharris 2903230557Sjimharris return TRUE; 2904230557Sjimharris } 2905230557Sjimharris 2906230557Sjimharris 2907230557Sjimharris if (interrupt_status != 0) 2908230557Sjimharris { 2909230557Sjimharris // There is an error interrupt pending so let it through and handle 2910230557Sjimharris // in the callback 2911230557Sjimharris return TRUE; 2912230557Sjimharris } 2913230557Sjimharris 2914230557Sjimharris // Clear any offending interrupts since we could not find any to handle 2915230557Sjimharris // and unmask them all 2916230557Sjimharris SMU_ISR_WRITE(this_controller, 0x00000000); 2917230557Sjimharris SMU_IMR_WRITE(this_controller, 0x00000000); 2918230557Sjimharris 2919230557Sjimharris return FALSE; 2920230557Sjimharris} 2921230557Sjimharris 2922230557Sjimharris/** 2923230557Sjimharris * @brief This is the method provided to handle completions for a single 2924230557Sjimharris * MSIX message. 2925230557Sjimharris * 2926230557Sjimharris * @param[in] controller 2927230557Sjimharris */ 2928230557Sjimharrisstatic 2929230557Sjimharrisvoid scic_sds_controller_single_vector_completion_handler( 2930230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 2931230557Sjimharris) 2932230557Sjimharris{ 2933230557Sjimharris U32 interrupt_status; 2934230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 2935230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 2936230557Sjimharris 2937230557Sjimharris SCIC_LOG_TRACE(( 2938230557Sjimharris sci_base_object_get_logger(controller), 2939230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2940230557Sjimharris "scic_sds_controller_single_vector_completion_handler(0x%d) enter\n", 2941230557Sjimharris controller 2942230557Sjimharris )); 2943230557Sjimharris 2944230557Sjimharris interrupt_status = SMU_ISR_READ(this_controller); 2945230557Sjimharris interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND); 2946230557Sjimharris 2947230557Sjimharris if (interrupt_status & SMU_ISR_QUEUE_ERROR) 2948230557Sjimharris { 2949230557Sjimharris SCIC_LOG_ERROR(( 2950230557Sjimharris sci_base_object_get_logger(this_controller), 2951230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2952230557Sjimharris "SCIC Controller has encountered a fatal error.\n" 2953230557Sjimharris )); 2954230557Sjimharris 2955230557Sjimharris // We have a fatal condition and must reset the controller 2956230557Sjimharris // Leave the interrupt mask in place and get the controller reset 2957230557Sjimharris sci_base_state_machine_change_state( 2958230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 2959230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED 2960230557Sjimharris ); 2961230557Sjimharris return; 2962230557Sjimharris } 2963230557Sjimharris 2964230557Sjimharris if ( 2965230557Sjimharris (interrupt_status & SMU_ISR_QUEUE_SUSPEND) 2966230557Sjimharris && !scic_sds_controller_completion_queue_has_entries(this_controller) 2967230557Sjimharris ) 2968230557Sjimharris { 2969230557Sjimharris SCIC_LOG_ERROR(( 2970230557Sjimharris sci_base_object_get_logger(this_controller), 2971230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 2972230557Sjimharris "SCIC Controller has encountered a fatal error.\n" 2973230557Sjimharris )); 2974230557Sjimharris 2975230557Sjimharris // We have a fatal condtion and must reset the controller 2976230557Sjimharris // Leave the interrupt mask in place and get the controller reset 2977230557Sjimharris sci_base_state_machine_change_state( 2978230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 2979230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED 2980230557Sjimharris ); 2981230557Sjimharris return; 2982230557Sjimharris } 2983230557Sjimharris 2984230557Sjimharris if (scic_sds_controller_completion_queue_has_entries(this_controller)) 2985230557Sjimharris { 2986230557Sjimharris scic_sds_controller_process_completions(this_controller); 2987230557Sjimharris 2988230557Sjimharris // We dont care which interrupt got us to processing the completion queu 2989230557Sjimharris // so clear them both. 2990230557Sjimharris SMU_ISR_WRITE( 2991230557Sjimharris this_controller, 2992230557Sjimharris (SMU_ISR_COMPLETION | SMU_ISR_QUEUE_SUSPEND) 2993230557Sjimharris ); 2994230557Sjimharris } 2995230557Sjimharris 2996230557Sjimharris SMU_IMR_WRITE(this_controller, 0x00000000); 2997230557Sjimharris} 2998230557Sjimharris 2999230557Sjimharris/** 3000230557Sjimharris * @brief This is the method provided to handle a MSIX message for a normal 3001230557Sjimharris * completion. 3002230557Sjimharris * 3003230557Sjimharris * @param[in] controller 3004230557Sjimharris * 3005230557Sjimharris * @return BOOL 3006230557Sjimharris * @retval TRUE if an interrupt is processed 3007230557Sjimharris * FALSE if no interrupt was processed 3008230557Sjimharris */ 3009230557Sjimharrisstatic 3010230557SjimharrisBOOL scic_sds_controller_normal_vector_interrupt_handler( 3011230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 3012230557Sjimharris) 3013230557Sjimharris{ 3014230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 3015230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 3016230557Sjimharris 3017230557Sjimharris if (scic_sds_controller_completion_queue_has_entries(this_controller)) 3018230557Sjimharris { 3019230557Sjimharris return TRUE; 3020230557Sjimharris } 3021230557Sjimharris else 3022230557Sjimharris { 3023230557Sjimharris // we have a spurious interrupt it could be that we have already 3024230557Sjimharris // emptied the completion queue from a previous interrupt 3025230557Sjimharris SMU_ISR_WRITE(this_controller, SMU_ISR_COMPLETION); 3026230557Sjimharris 3027230557Sjimharris // There is a race in the hardware that could cause us not to be notified 3028230557Sjimharris // of an interrupt completion if we do not take this step. We will mask 3029230557Sjimharris // then unmask the interrupts so if there is another interrupt pending 3030230557Sjimharris // the clearing of the interrupt source we get the next interrupt message. 3031230557Sjimharris SMU_IMR_WRITE(this_controller, 0xFF000000); 3032230557Sjimharris SMU_IMR_WRITE(this_controller, 0x00000000); 3033230557Sjimharris } 3034230557Sjimharris 3035230557Sjimharris return FALSE; 3036230557Sjimharris} 3037230557Sjimharris 3038230557Sjimharris/** 3039230557Sjimharris * @brief This is the method provided to handle the completions for a 3040230557Sjimharris * normal MSIX message. 3041230557Sjimharris * 3042230557Sjimharris * @param[in] controller 3043230557Sjimharris */ 3044230557Sjimharrisstatic 3045230557Sjimharrisvoid scic_sds_controller_normal_vector_completion_handler( 3046230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 3047230557Sjimharris) 3048230557Sjimharris{ 3049230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 3050230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 3051230557Sjimharris 3052230557Sjimharris SCIC_LOG_TRACE(( 3053230557Sjimharris sci_base_object_get_logger(controller), 3054230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 3055230557Sjimharris "scic_sds_controller_normal_vector_completion_handler(0x%d) enter\n", 3056230557Sjimharris controller 3057230557Sjimharris )); 3058230557Sjimharris 3059230557Sjimharris // Empty out the completion queue 3060230557Sjimharris if (scic_sds_controller_completion_queue_has_entries(this_controller)) 3061230557Sjimharris { 3062230557Sjimharris scic_sds_controller_process_completions(this_controller); 3063230557Sjimharris } 3064230557Sjimharris 3065230557Sjimharris // Clear the interrupt and enable all interrupts again 3066230557Sjimharris SMU_ISR_WRITE(this_controller, SMU_ISR_COMPLETION); 3067230557Sjimharris // Could we write the value of SMU_ISR_COMPLETION? 3068230557Sjimharris SMU_IMR_WRITE(this_controller, 0xFF000000); 3069230557Sjimharris SMU_IMR_WRITE(this_controller, 0x00000000); 3070230557Sjimharris} 3071230557Sjimharris 3072230557Sjimharris/** 3073230557Sjimharris * @brief This is the method provided to handle the error MSIX message 3074230557Sjimharris * interrupt. This is the normal operating mode for the hardware if 3075230557Sjimharris * MSIX is enabled. 3076230557Sjimharris * 3077230557Sjimharris * @param[in] controller 3078230557Sjimharris * 3079230557Sjimharris * @return BOOL 3080230557Sjimharris * @retval TRUE if an interrupt is processed 3081230557Sjimharris * FALSE if no interrupt was processed 3082230557Sjimharris */ 3083230557Sjimharrisstatic 3084230557SjimharrisBOOL scic_sds_controller_error_vector_interrupt_handler( 3085230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 3086230557Sjimharris) 3087230557Sjimharris{ 3088230557Sjimharris U32 interrupt_status; 3089230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 3090230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 3091230557Sjimharris 3092230557Sjimharris 3093230557Sjimharris interrupt_status = SMU_ISR_READ(this_controller); 3094230557Sjimharris interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND); 3095230557Sjimharris 3096230557Sjimharris if (interrupt_status != 0) 3097230557Sjimharris { 3098230557Sjimharris // There is an error interrupt pending so let it through and handle 3099230557Sjimharris // in the callback 3100230557Sjimharris return TRUE; 3101230557Sjimharris } 3102230557Sjimharris 3103230557Sjimharris // There is a race in the hardware that could cause us not to be notified 3104230557Sjimharris // of an interrupt completion if we do not take this step. We will mask 3105230557Sjimharris // then unmask the error interrupts so if there was another interrupt 3106230557Sjimharris // pending we will be notified. 3107230557Sjimharris // Could we write the value of (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND)? 3108230557Sjimharris SMU_IMR_WRITE(this_controller, 0x000000FF); 3109230557Sjimharris SMU_IMR_WRITE(this_controller, 0x00000000); 3110230557Sjimharris 3111230557Sjimharris return FALSE; 3112230557Sjimharris} 3113230557Sjimharris 3114230557Sjimharris/** 3115230557Sjimharris * @brief This is the method provided to handle the error completions when 3116230557Sjimharris * the hardware is using two MSIX messages. 3117230557Sjimharris * 3118230557Sjimharris * @param[in] controller 3119230557Sjimharris */ 3120230557Sjimharrisstatic 3121230557Sjimharrisvoid scic_sds_controller_error_vector_completion_handler( 3122230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 3123230557Sjimharris) 3124230557Sjimharris{ 3125230557Sjimharris U32 interrupt_status; 3126230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 3127230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 3128230557Sjimharris 3129230557Sjimharris SCIC_LOG_TRACE(( 3130230557Sjimharris sci_base_object_get_logger(controller), 3131230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 3132230557Sjimharris "scic_sds_controller_error_vector_completion_handler(0x%d) enter\n", 3133230557Sjimharris controller 3134230557Sjimharris )); 3135230557Sjimharris 3136230557Sjimharris interrupt_status = SMU_ISR_READ(this_controller); 3137230557Sjimharris 3138230557Sjimharris if ( 3139230557Sjimharris (interrupt_status & SMU_ISR_QUEUE_SUSPEND) 3140230557Sjimharris && scic_sds_controller_completion_queue_has_entries(this_controller) 3141230557Sjimharris ) 3142230557Sjimharris { 3143230557Sjimharris scic_sds_controller_process_completions(this_controller); 3144230557Sjimharris 3145230557Sjimharris SMU_ISR_WRITE(this_controller, SMU_ISR_QUEUE_SUSPEND); 3146230557Sjimharris } 3147230557Sjimharris else 3148230557Sjimharris { 3149230557Sjimharris SCIC_LOG_ERROR(( 3150230557Sjimharris sci_base_object_get_logger(this_controller), 3151230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 3152230557Sjimharris "SCIC Controller reports CRC error on completion ISR %x\n", 3153230557Sjimharris interrupt_status 3154230557Sjimharris )); 3155230557Sjimharris 3156230557Sjimharris sci_base_state_machine_change_state( 3157230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 3158230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED 3159230557Sjimharris ); 3160230557Sjimharris 3161230557Sjimharris return; 3162230557Sjimharris } 3163230557Sjimharris 3164230557Sjimharris // If we dont process any completions I am not sure that we want to do this. 3165230557Sjimharris // We are in the middle of a hardware fault and should probably be reset. 3166230557Sjimharris SMU_IMR_WRITE(this_controller, 0x00000000); 3167230557Sjimharris} 3168230557Sjimharris 3169230557Sjimharris#endif // !defined(DISABLE_INTERRUPTS) 3170230557Sjimharris 3171230557Sjimharris//****************************************************************************- 3172230557Sjimharris//* SCIC SDS Controller External Methods 3173230557Sjimharris//****************************************************************************- 3174230557Sjimharris 3175230557Sjimharris/** 3176230557Sjimharris * @brief This method returns the sizeof the SCIC SDS Controller Object 3177230557Sjimharris * 3178230557Sjimharris * @return U32 3179230557Sjimharris */ 3180230557SjimharrisU32 scic_sds_controller_get_object_size(void) 3181230557Sjimharris{ 3182230557Sjimharris return sizeof(SCIC_SDS_CONTROLLER_T); 3183230557Sjimharris} 3184230557Sjimharris 3185230557Sjimharris/** 3186230557Sjimharris * This method returns the minimum number of timers that are required by the 3187230557Sjimharris * controller object. This will include required timers for phys and ports. 3188230557Sjimharris * 3189230557Sjimharris * @return U32 3190230557Sjimharris * @retval The minimum number of timers that are required to make this 3191230557Sjimharris * controller operational. 3192230557Sjimharris */ 3193230557SjimharrisU32 scic_sds_controller_get_min_timer_count(void) 3194230557Sjimharris{ 3195230557Sjimharris return SCIC_SDS_CONTROLLER_MIN_TIMER_COUNT 3196230557Sjimharris + scic_sds_port_get_min_timer_count() 3197230557Sjimharris + scic_sds_phy_get_min_timer_count(); 3198230557Sjimharris} 3199230557Sjimharris 3200230557Sjimharris/** 3201230557Sjimharris * This method returns the maximum number of timers that are required by the 3202230557Sjimharris * controller object. This will include required timers for phys and ports. 3203230557Sjimharris * 3204230557Sjimharris * @return U32 3205230557Sjimharris * @retval The maximum number of timers that will be used by the controller 3206230557Sjimharris * object 3207230557Sjimharris */ 3208230557SjimharrisU32 scic_sds_controller_get_max_timer_count(void) 3209230557Sjimharris{ 3210230557Sjimharris return SCIC_SDS_CONTROLLER_MAX_TIMER_COUNT 3211230557Sjimharris + scic_sds_port_get_max_timer_count() 3212230557Sjimharris + scic_sds_phy_get_max_timer_count(); 3213230557Sjimharris} 3214230557Sjimharris 3215230557Sjimharris/** 3216230557Sjimharris * @brief 3217230557Sjimharris * 3218230557Sjimharris * @param[in] this_controller 3219230557Sjimharris * @param[in] the_port 3220230557Sjimharris * @param[in] the_phy 3221230557Sjimharris * 3222230557Sjimharris * @return none 3223230557Sjimharris */ 3224230557Sjimharrisvoid scic_sds_controller_link_up( 3225230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 3226230557Sjimharris SCIC_SDS_PORT_T *the_port, 3227230557Sjimharris SCIC_SDS_PHY_T *the_phy 3228230557Sjimharris) 3229230557Sjimharris{ 3230230557Sjimharris if (this_controller->state_handlers->link_up_handler != NULL) 3231230557Sjimharris { 3232230557Sjimharris this_controller->state_handlers->link_up_handler( 3233230557Sjimharris this_controller, the_port, the_phy); 3234230557Sjimharris } 3235230557Sjimharris else 3236230557Sjimharris { 3237230557Sjimharris SCIC_LOG_INFO(( 3238230557Sjimharris sci_base_object_get_logger(this_controller), 3239230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 3240230557Sjimharris "SCIC Controller linkup event from phy %d in unexpected state %d\n", 3241230557Sjimharris the_phy->phy_index, 3242230557Sjimharris sci_base_state_machine_get_state( 3243230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller)) 3244230557Sjimharris )); 3245230557Sjimharris } 3246230557Sjimharris} 3247230557Sjimharris 3248230557Sjimharris/** 3249230557Sjimharris * @brief 3250230557Sjimharris * 3251230557Sjimharris * @param[in] this_controller 3252230557Sjimharris * @param[in] the_port 3253230557Sjimharris * @param[in] the_phy 3254230557Sjimharris */ 3255230557Sjimharrisvoid scic_sds_controller_link_down( 3256230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 3257230557Sjimharris SCIC_SDS_PORT_T *the_port, 3258230557Sjimharris SCIC_SDS_PHY_T *the_phy 3259230557Sjimharris) 3260230557Sjimharris{ 3261230557Sjimharris if (this_controller->state_handlers->link_down_handler != NULL) 3262230557Sjimharris { 3263230557Sjimharris this_controller->state_handlers->link_down_handler( 3264230557Sjimharris this_controller, the_port, the_phy); 3265230557Sjimharris } 3266230557Sjimharris else 3267230557Sjimharris { 3268230557Sjimharris SCIC_LOG_INFO(( 3269230557Sjimharris sci_base_object_get_logger(this_controller), 3270230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 3271230557Sjimharris "SCIC Controller linkdown event from phy %d in unexpected state %d\n", 3272230557Sjimharris the_phy->phy_index, 3273230557Sjimharris sci_base_state_machine_get_state( 3274230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller)) 3275230557Sjimharris )); 3276230557Sjimharris } 3277230557Sjimharris} 3278230557Sjimharris 3279230557Sjimharris/** 3280230557Sjimharris * @brief This method is called by the remote device to inform the controller 3281230557Sjimharris * that this remote device has started. 3282230557Sjimharris * 3283230557Sjimharris * @param[in] this_controller 3284230557Sjimharris * @param[in] the_device 3285230557Sjimharris */ 3286230557Sjimharrisvoid scic_sds_controller_remote_device_started( 3287230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller, 3288230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * the_device 3289230557Sjimharris) 3290230557Sjimharris{ 3291230557Sjimharris if (this_controller->state_handlers->remote_device_started_handler != NULL) 3292230557Sjimharris { 3293230557Sjimharris this_controller->state_handlers->remote_device_started_handler( 3294230557Sjimharris this_controller, the_device 3295230557Sjimharris ); 3296230557Sjimharris } 3297230557Sjimharris else 3298230557Sjimharris { 3299230557Sjimharris SCIC_LOG_INFO(( 3300230557Sjimharris sci_base_object_get_logger(this_controller), 3301230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 3302230557Sjimharris "SCIC Controller 0x%x remote device started event from device 0x%x in unexpected state %d\n", 3303230557Sjimharris this_controller, 3304230557Sjimharris the_device, 3305230557Sjimharris sci_base_state_machine_get_state( 3306230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller)) 3307230557Sjimharris )); 3308230557Sjimharris } 3309230557Sjimharris} 3310230557Sjimharris 3311230557Sjimharris/** 3312230557Sjimharris * @brief This is a helper method to determine if any remote devices on this 3313230557Sjimharris * controller are still in the stopping state. 3314230557Sjimharris * 3315230557Sjimharris * @param[in] this_controller 3316230557Sjimharris */ 3317230557SjimharrisBOOL scic_sds_controller_has_remote_devices_stopping( 3318230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller 3319230557Sjimharris) 3320230557Sjimharris{ 3321230557Sjimharris U32 index; 3322230557Sjimharris 3323230557Sjimharris for (index = 0; index < this_controller->remote_node_entries; index++) 3324230557Sjimharris { 3325230557Sjimharris if ( 3326230557Sjimharris (this_controller->device_table[index] != NULL) 3327230557Sjimharris && ( 3328230557Sjimharris this_controller->device_table[index]->parent.state_machine.current_state_id 3329230557Sjimharris == SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 3330230557Sjimharris ) 3331230557Sjimharris ) 3332230557Sjimharris { 3333230557Sjimharris return TRUE; 3334230557Sjimharris } 3335230557Sjimharris } 3336230557Sjimharris 3337230557Sjimharris return FALSE; 3338230557Sjimharris} 3339230557Sjimharris 3340230557Sjimharris/** 3341230557Sjimharris * @brief This method is called by the remote device to inform the controller 3342230557Sjimharris * object that the remote device has stopped. 3343230557Sjimharris * 3344230557Sjimharris * @param[in] this_controller 3345230557Sjimharris * @param[in] the_device 3346230557Sjimharris */ 3347230557Sjimharrisvoid scic_sds_controller_remote_device_stopped( 3348230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller, 3349230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * the_device 3350230557Sjimharris) 3351230557Sjimharris{ 3352230557Sjimharris if (this_controller->state_handlers->remote_device_stopped_handler != NULL) 3353230557Sjimharris { 3354230557Sjimharris this_controller->state_handlers->remote_device_stopped_handler( 3355230557Sjimharris this_controller, the_device 3356230557Sjimharris ); 3357230557Sjimharris } 3358230557Sjimharris else 3359230557Sjimharris { 3360230557Sjimharris SCIC_LOG_INFO(( 3361230557Sjimharris sci_base_object_get_logger(this_controller), 3362230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 3363230557Sjimharris "SCIC Controller 0x%x remote device stopped event from device 0x%x in unexpected state %d\n", 3364230557Sjimharris this_controller, 3365230557Sjimharris the_device, 3366230557Sjimharris sci_base_state_machine_get_state( 3367230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller)) 3368230557Sjimharris )); 3369230557Sjimharris } 3370230557Sjimharris} 3371230557Sjimharris 3372230557Sjimharris/** 3373230557Sjimharris * @brief This method will write to the SCU PCP register the request value. 3374230557Sjimharris * The method is used to suspend/resume ports, devices, and phys. 3375230557Sjimharris * 3376230557Sjimharris * @param[in] this_controller 3377230557Sjimharris * @param[in] request 3378230557Sjimharris */ 3379230557Sjimharrisvoid scic_sds_controller_post_request( 3380230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 3381230557Sjimharris U32 request 3382230557Sjimharris) 3383230557Sjimharris{ 3384230557Sjimharris SCIC_LOG_INFO(( 3385230557Sjimharris sci_base_object_get_logger(this_controller), 3386230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_COMPLETION_QUEUE, 3387230557Sjimharris "SCIC Controller 0x%08x post request 0x%08x\n", 3388230557Sjimharris this_controller, request 3389230557Sjimharris )); 3390230557Sjimharris 3391230557Sjimharris SMU_PCP_WRITE(this_controller, request); 3392230557Sjimharris} 3393230557Sjimharris 3394230557Sjimharris/** 3395230557Sjimharris * @brief This method will copy the soft copy of the task context into 3396230557Sjimharris * the physical memory accessible by the controller. 3397230557Sjimharris * 3398230557Sjimharris * @note After this call is made the SCIC_SDS_IO_REQUEST object will 3399230557Sjimharris * always point to the physical memory version of the task context. 3400230557Sjimharris * Thus, all subsequent updates to the task context are performed in 3401230557Sjimharris * the TC table (i.e. DMAable memory). 3402230557Sjimharris * 3403230557Sjimharris * @param[in] this_controller This parameter specifies the controller for 3404230557Sjimharris * which to copy the task context. 3405230557Sjimharris * @param[in] this_request This parameter specifies the request for which 3406230557Sjimharris * the task context is being copied. 3407230557Sjimharris * 3408230557Sjimharris * @return none 3409230557Sjimharris */ 3410230557Sjimharrisvoid scic_sds_controller_copy_task_context( 3411230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 3412230557Sjimharris SCIC_SDS_REQUEST_T *this_request 3413230557Sjimharris) 3414230557Sjimharris{ 3415230557Sjimharris SCU_TASK_CONTEXT_T *task_context_buffer; 3416230557Sjimharris 3417230557Sjimharris task_context_buffer = scic_sds_controller_get_task_context_buffer( 3418230557Sjimharris this_controller, this_request->io_tag 3419230557Sjimharris ); 3420230557Sjimharris 3421230557Sjimharris memcpy( 3422230557Sjimharris task_context_buffer, 3423230557Sjimharris this_request->task_context_buffer, 3424230557Sjimharris SCI_FIELD_OFFSET(SCU_TASK_CONTEXT_T, sgl_snapshot_ac) 3425230557Sjimharris ); 3426230557Sjimharris 3427230557Sjimharris // Now that the soft copy of the TC has been copied into the TC 3428230557Sjimharris // table accessible by the silicon. Thus, any further changes to 3429230557Sjimharris // the TC (e.g. TC termination) occur in the appropriate location. 3430230557Sjimharris this_request->task_context_buffer = task_context_buffer; 3431230557Sjimharris} 3432230557Sjimharris 3433230557Sjimharris/** 3434230557Sjimharris * @brief This method returns the task context buffer for the given io tag. 3435230557Sjimharris * 3436230557Sjimharris * @param[in] this_controller 3437230557Sjimharris * @param[in] io_tag 3438230557Sjimharris * 3439230557Sjimharris * @return struct SCU_TASK_CONTEXT* 3440230557Sjimharris */ 3441230557SjimharrisSCU_TASK_CONTEXT_T * scic_sds_controller_get_task_context_buffer( 3442230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller, 3443230557Sjimharris U16 io_tag 3444230557Sjimharris) 3445230557Sjimharris{ 3446230557Sjimharris U16 task_index = scic_sds_io_tag_get_index(io_tag); 3447230557Sjimharris 3448230557Sjimharris if (task_index < this_controller->task_context_entries) 3449230557Sjimharris { 3450230557Sjimharris return &this_controller->task_context_table[task_index]; 3451230557Sjimharris } 3452230557Sjimharris 3453230557Sjimharris return NULL; 3454230557Sjimharris} 3455230557Sjimharris 3456230557Sjimharris/** 3457230557Sjimharris * @brief This method returnst the sequence value from the io tag value 3458230557Sjimharris * 3459230557Sjimharris * @param[in] this_controller 3460230557Sjimharris * @param[in] io_tag 3461230557Sjimharris * 3462230557Sjimharris * @return U16 3463230557Sjimharris */ 3464230557SjimharrisU16 scic_sds_controller_get_io_sequence_from_tag( 3465230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 3466230557Sjimharris U16 io_tag 3467230557Sjimharris) 3468230557Sjimharris{ 3469230557Sjimharris return scic_sds_io_tag_get_sequence(io_tag); 3470230557Sjimharris} 3471230557Sjimharris 3472230557Sjimharris/** 3473230557Sjimharris * @brief This method returns the IO request associated with the tag value 3474230557Sjimharris * 3475230557Sjimharris * @param[in] this_controller 3476230557Sjimharris * @param[in] io_tag 3477230557Sjimharris * 3478230557Sjimharris * @return SCIC_SDS_IO_REQUEST_T* 3479230557Sjimharris * @retval NULL if there is no valid IO request at the tag value 3480230557Sjimharris */ 3481230557SjimharrisSCIC_SDS_REQUEST_T *scic_sds_controller_get_io_request_from_tag( 3482230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 3483230557Sjimharris U16 io_tag 3484230557Sjimharris) 3485230557Sjimharris{ 3486230557Sjimharris U16 task_index; 3487230557Sjimharris U16 task_sequence; 3488230557Sjimharris 3489230557Sjimharris task_index = scic_sds_io_tag_get_index(io_tag); 3490230557Sjimharris 3491230557Sjimharris if (task_index < this_controller->task_context_entries) 3492230557Sjimharris { 3493230557Sjimharris if (this_controller->io_request_table[task_index] != SCI_INVALID_HANDLE) 3494230557Sjimharris { 3495230557Sjimharris task_sequence = scic_sds_io_tag_get_sequence(io_tag); 3496230557Sjimharris 3497230557Sjimharris if (task_sequence == this_controller->io_request_sequence[task_index]) 3498230557Sjimharris { 3499230557Sjimharris return this_controller->io_request_table[task_index]; 3500230557Sjimharris } 3501230557Sjimharris } 3502230557Sjimharris } 3503230557Sjimharris 3504230557Sjimharris return SCI_INVALID_HANDLE; 3505230557Sjimharris} 3506230557Sjimharris 3507230557Sjimharris/** 3508230557Sjimharris * @brief This method allocates remote node index and the reserves the 3509230557Sjimharris * remote node context space for use. This method can fail if there 3510230557Sjimharris * are no more remote node index available. 3511230557Sjimharris * 3512230557Sjimharris * @param[in] this_controller This is the controller object which contains 3513230557Sjimharris * the set of free remote node ids 3514230557Sjimharris * @param[in] the_devce This is the device object which is requesting the a 3515230557Sjimharris * remote node id 3516230557Sjimharris * @param[out] node_id This is the remote node id that is assinged to the 3517230557Sjimharris * device if one is available 3518230557Sjimharris * 3519230557Sjimharris * @return SCI_STATUS 3520230557Sjimharris * @retval SCI_FAILURE_OUT_OF_RESOURCES if there are no available remote 3521230557Sjimharris * node index available. 3522230557Sjimharris */ 3523230557SjimharrisSCI_STATUS scic_sds_controller_allocate_remote_node_context( 3524230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller, 3525230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * the_device, 3526230557Sjimharris U16 * node_id 3527230557Sjimharris) 3528230557Sjimharris{ 3529230557Sjimharris U16 node_index; 3530230557Sjimharris U32 remote_node_count = scic_sds_remote_device_node_count(the_device); 3531230557Sjimharris 3532230557Sjimharris node_index = scic_sds_remote_node_table_allocate_remote_node( 3533230557Sjimharris &this_controller->available_remote_nodes, remote_node_count 3534230557Sjimharris ); 3535230557Sjimharris 3536230557Sjimharris if (node_index != SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) 3537230557Sjimharris { 3538230557Sjimharris this_controller->device_table[node_index] = the_device; 3539230557Sjimharris 3540230557Sjimharris *node_id = node_index; 3541230557Sjimharris 3542230557Sjimharris return SCI_SUCCESS; 3543230557Sjimharris } 3544230557Sjimharris 3545230557Sjimharris return SCI_FAILURE_INSUFFICIENT_RESOURCES; 3546230557Sjimharris} 3547230557Sjimharris 3548230557Sjimharris/** 3549230557Sjimharris * @brief This method frees the remote node index back to the available 3550230557Sjimharris * pool. Once this is done the remote node context buffer is no 3551230557Sjimharris * longer valid and can not be used. 3552230557Sjimharris * 3553230557Sjimharris * @param[in] this_controller 3554230557Sjimharris * @param[in] the_device 3555230557Sjimharris * @param[in] node_id 3556230557Sjimharris * 3557230557Sjimharris * @return none 3558230557Sjimharris */ 3559230557Sjimharrisvoid scic_sds_controller_free_remote_node_context( 3560230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller, 3561230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * the_device, 3562230557Sjimharris U16 node_id 3563230557Sjimharris) 3564230557Sjimharris{ 3565230557Sjimharris U32 remote_node_count = scic_sds_remote_device_node_count(the_device); 3566230557Sjimharris 3567230557Sjimharris if (this_controller->device_table[node_id] == the_device) 3568230557Sjimharris { 3569230557Sjimharris this_controller->device_table[node_id] = SCI_INVALID_HANDLE; 3570230557Sjimharris 3571230557Sjimharris scic_sds_remote_node_table_release_remote_node_index( 3572230557Sjimharris &this_controller->available_remote_nodes, remote_node_count, node_id 3573230557Sjimharris ); 3574230557Sjimharris } 3575230557Sjimharris} 3576230557Sjimharris 3577230557Sjimharris/** 3578230557Sjimharris * @brief This method returns the SCU_REMOTE_NODE_CONTEXT for the specified 3579230557Sjimharris * remote node id. 3580230557Sjimharris * 3581230557Sjimharris * @param[in] this_controller 3582230557Sjimharris * @param[in] node_id 3583230557Sjimharris * 3584230557Sjimharris * @return SCU_REMOTE_NODE_CONTEXT_T* 3585230557Sjimharris */ 3586230557SjimharrisSCU_REMOTE_NODE_CONTEXT_T *scic_sds_controller_get_remote_node_context_buffer( 3587230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 3588230557Sjimharris U16 node_id 3589230557Sjimharris) 3590230557Sjimharris{ 3591230557Sjimharris if ( 3592230557Sjimharris (node_id < this_controller->remote_node_entries) 3593230557Sjimharris && (this_controller->device_table[node_id] != SCI_INVALID_HANDLE) 3594230557Sjimharris ) 3595230557Sjimharris { 3596230557Sjimharris return &this_controller->remote_node_context_table[node_id]; 3597230557Sjimharris } 3598230557Sjimharris 3599230557Sjimharris return NULL; 3600230557Sjimharris} 3601230557Sjimharris 3602230557Sjimharris/** 3603230557Sjimharris * This method will combind the frame header and frame buffer to create 3604230557Sjimharris * a SATA D2H register FIS 3605230557Sjimharris * 3606230557Sjimharris * @param[out] resposne_buffer This is the buffer into which the D2H register 3607230557Sjimharris * FIS will be constructed. 3608230557Sjimharris * @param[in] frame_header This is the frame header returned by the hardware. 3609230557Sjimharris * @param[in] frame_buffer This is the frame buffer returned by the hardware. 3610230557Sjimharris * 3611230557Sjimharris * @erturn none 3612230557Sjimharris */ 3613230557Sjimharrisvoid scic_sds_controller_copy_sata_response( 3614230557Sjimharris void * response_buffer, 3615230557Sjimharris void * frame_header, 3616230557Sjimharris void * frame_buffer 3617230557Sjimharris) 3618230557Sjimharris{ 3619230557Sjimharris memcpy( 3620230557Sjimharris response_buffer, 3621230557Sjimharris frame_header, 3622230557Sjimharris sizeof(U32) 3623230557Sjimharris ); 3624230557Sjimharris 3625230557Sjimharris memcpy( 3626230557Sjimharris (char *)((char *)response_buffer + sizeof(U32)), 3627230557Sjimharris frame_buffer, 3628230557Sjimharris sizeof(SATA_FIS_REG_D2H_T) - sizeof(U32) 3629230557Sjimharris ); 3630230557Sjimharris} 3631230557Sjimharris 3632230557Sjimharris/** 3633230557Sjimharris * @brief This method releases the frame once this is done the frame is 3634230557Sjimharris * available for re-use by the hardware. The data contained in the 3635230557Sjimharris * frame header and frame buffer is no longer valid. 3636230557Sjimharris * The UF queue get pointer is only updated if UF control indicates 3637230557Sjimharris * this is appropriate. 3638230557Sjimharris * 3639230557Sjimharris * @param[in] this_controller 3640230557Sjimharris * @param[in] frame_index 3641230557Sjimharris * 3642230557Sjimharris * @return none 3643230557Sjimharris */ 3644230557Sjimharrisvoid scic_sds_controller_release_frame( 3645230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 3646230557Sjimharris U32 frame_index 3647230557Sjimharris) 3648230557Sjimharris{ 3649230557Sjimharris if (scic_sds_unsolicited_frame_control_release_frame( 3650230557Sjimharris &this_controller->uf_control, frame_index) == TRUE) 3651230557Sjimharris SCU_UFQGP_WRITE(this_controller, this_controller->uf_control.get); 3652230557Sjimharris} 3653230557Sjimharris 3654230557Sjimharris#ifdef SCI_LOGGING 3655230557Sjimharrisvoid scic_sds_controller_initialize_state_logging( 3656230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 3657230557Sjimharris) 3658230557Sjimharris{ 3659230557Sjimharris sci_base_state_machine_logger_initialize( 3660230557Sjimharris &this_controller->parent.state_machine_logger, 3661230557Sjimharris &this_controller->parent.state_machine, 3662230557Sjimharris &this_controller->parent.parent, 3663230557Sjimharris scic_cb_logger_log_states, 3664230557Sjimharris "SCIC_SDS_CONTROLLER_T", "base state machine", 3665230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER 3666230557Sjimharris ); 3667230557Sjimharris} 3668230557Sjimharris 3669230557Sjimharrisvoid scic_sds_controller_deinitialize_state_logging( 3670230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 3671230557Sjimharris) 3672230557Sjimharris{ 3673230557Sjimharris sci_base_state_machine_logger_deinitialize( 3674230557Sjimharris &this_controller->parent.state_machine_logger, 3675230557Sjimharris &this_controller->parent.state_machine 3676230557Sjimharris ); 3677230557Sjimharris} 3678230557Sjimharris#endif 3679230557Sjimharris 3680230557Sjimharris/** 3681230557Sjimharris * @brief This method sets user parameters and OEM parameters to 3682230557Sjimharris * default values. Users can override these values utilizing 3683230557Sjimharris * the scic_user_parameters_set() and scic_oem_parameters_set() 3684230557Sjimharris * methods. 3685230557Sjimharris * 3686230557Sjimharris * @param[in] controller This parameter specifies the controller for 3687230557Sjimharris * which to set the configuration parameters to their 3688230557Sjimharris * default values. 3689230557Sjimharris * 3690230557Sjimharris * @return none 3691230557Sjimharris */ 3692230557Sjimharrisstatic 3693230557Sjimharrisvoid scic_sds_controller_set_default_config_parameters( 3694230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller 3695230557Sjimharris) 3696230557Sjimharris{ 3697230557Sjimharris U16 index; 3698230557Sjimharris 3699230557Sjimharris // Default to APC mode. 3700230557Sjimharris this_controller->oem_parameters.sds1.controller.mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE; 3701230557Sjimharris 3702230557Sjimharris // Default to 1 3703230557Sjimharris this_controller->oem_parameters.sds1.controller.max_number_concurrent_device_spin_up = 1; 3704230557Sjimharris 3705230557Sjimharris // Default to no SSC operation. 3706230557Sjimharris this_controller->oem_parameters.sds1.controller.ssc_sata_tx_spread_level = 0; 3707230557Sjimharris this_controller->oem_parameters.sds1.controller.ssc_sas_tx_spread_level = 0; 3708230557Sjimharris this_controller->oem_parameters.sds1.controller.ssc_sas_tx_type = 0; 3709230557Sjimharris 3710230557Sjimharris // Default to all phys to using short cables 3711230557Sjimharris this_controller->oem_parameters.sds1.controller.cable_selection_mask = 0; 3712230557Sjimharris 3713230557Sjimharris // Initialize all of the port parameter information to narrow ports. 3714230557Sjimharris for (index = 0; index < SCI_MAX_PORTS; index++) 3715230557Sjimharris { 3716230557Sjimharris this_controller->oem_parameters.sds1.ports[index].phy_mask = 0; 3717230557Sjimharris } 3718230557Sjimharris 3719230557Sjimharris // Initialize all of the phy parameter information. 3720230557Sjimharris for (index = 0; index < SCI_MAX_PHYS; index++) 3721230557Sjimharris { 3722230557Sjimharris // Default to 6G (i.e. Gen 3) for now. User can override if 3723230557Sjimharris // they choose. 3724230557Sjimharris this_controller->user_parameters.sds1.phys[index].max_speed_generation = 2; 3725230557Sjimharris 3726230557Sjimharris //the frequencies cannot be 0 3727230557Sjimharris this_controller->user_parameters.sds1.phys[index].align_insertion_frequency = 0x7f; 3728230557Sjimharris this_controller->user_parameters.sds1.phys[index].in_connection_align_insertion_frequency = 0xff; 3729230557Sjimharris this_controller->user_parameters.sds1.phys[index].notify_enable_spin_up_insertion_frequency = 0x33; 3730230557Sjimharris 3731230557Sjimharris // Previous Vitesse based expanders had a arbitration issue that 3732230557Sjimharris // is worked around by having the upper 32-bits of SAS address 3733230557Sjimharris // with a value greater then the Vitesse company identifier. 3734230557Sjimharris // Hence, usage of 0x5FCFFFFF. 3735230557Sjimharris this_controller->oem_parameters.sds1.phys[index].sas_address.sci_format.high 3736230557Sjimharris = 0x5FCFFFFF; 3737230557Sjimharris 3738230557Sjimharris // Add in controller index to ensure each controller will have unique SAS addresses by default. 3739230557Sjimharris this_controller->oem_parameters.sds1.phys[index].sas_address.sci_format.low 3740230557Sjimharris = 0x00000001 + this_controller->controller_index; 3741230557Sjimharris 3742230557Sjimharris if ( (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0) 3743230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) 3744230557Sjimharris || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0) ) 3745230557Sjimharris { 3746230557Sjimharris this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control0 = 0x000E7C03; 3747230557Sjimharris this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control1 = 0x000E7C03; 3748230557Sjimharris this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control2 = 0x000E7C03; 3749230557Sjimharris this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control3 = 0x000E7C03; 3750230557Sjimharris } 3751230557Sjimharris else // This must be SCIC_SDS_PCI_REVISION_C0 3752230557Sjimharris { 3753230557Sjimharris this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control0 = 0x000BDD08; 3754230557Sjimharris this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control1 = 0x000B7069; 3755230557Sjimharris this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control2 = 0x000B7C09; 3756230557Sjimharris this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control3 = 0x000AFC6E; 3757230557Sjimharris } 3758230557Sjimharris } 3759230557Sjimharris 3760230557Sjimharris this_controller->user_parameters.sds1.stp_inactivity_timeout = 5; 3761230557Sjimharris this_controller->user_parameters.sds1.ssp_inactivity_timeout = 5; 3762230557Sjimharris this_controller->user_parameters.sds1.stp_max_occupancy_timeout = 5; 3763230557Sjimharris this_controller->user_parameters.sds1.ssp_max_occupancy_timeout = 20; 3764230557Sjimharris this_controller->user_parameters.sds1.no_outbound_task_timeout = 20; 3765230557Sjimharris 3766230557Sjimharris} 3767230557Sjimharris 3768230557Sjimharris 3769230557Sjimharris/** 3770230557Sjimharris * @brief This method release resources in SCI controller. 3771230557Sjimharris * 3772230557Sjimharris * @param[in] this_controller This parameter specifies the core 3773230557Sjimharris * controller and associated objects whose resources are to be 3774230557Sjimharris * released. 3775230557Sjimharris * 3776230557Sjimharris * @return This method returns a value indicating if the operation succeeded. 3777230557Sjimharris * @retval SCI_SUCCESS This value indicates that all the timers are destroyed. 3778230557Sjimharris * @retval SCI_FAILURE This value indicates certain failure during the process 3779230557Sjimharris * of cleaning timer resource. 3780230557Sjimharris */ 3781230557Sjimharrisstatic 3782230557SjimharrisSCI_STATUS scic_sds_controller_release_resource( 3783230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller 3784230557Sjimharris) 3785230557Sjimharris{ 3786230557Sjimharris SCIC_SDS_PORT_T * port; 3787230557Sjimharris SCIC_SDS_PHY_T * phy; 3788230557Sjimharris U8 index; 3789230557Sjimharris 3790230557Sjimharris SCIC_LOG_TRACE(( 3791230557Sjimharris sci_base_object_get_logger(this_controller), 3792230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_INITIALIZATION, 3793230557Sjimharris "scic_sds_controller_release_resource(0x%x) enter\n", 3794230557Sjimharris this_controller 3795230557Sjimharris )); 3796230557Sjimharris 3797230557Sjimharris if(this_controller->phy_startup_timer != NULL) 3798230557Sjimharris { 3799230557Sjimharris scic_cb_timer_destroy(this_controller, this_controller->phy_startup_timer); 3800230557Sjimharris this_controller->phy_startup_timer = NULL; 3801230557Sjimharris } 3802230557Sjimharris 3803230557Sjimharris if(this_controller->power_control.timer != NULL) 3804230557Sjimharris { 3805230557Sjimharris scic_cb_timer_destroy(this_controller, this_controller->power_control.timer); 3806230557Sjimharris this_controller->power_control.timer = NULL; 3807230557Sjimharris } 3808230557Sjimharris 3809230557Sjimharris if(this_controller->timeout_timer != NULL) 3810230557Sjimharris { 3811230557Sjimharris scic_cb_timer_destroy(this_controller, this_controller->timeout_timer); 3812230557Sjimharris this_controller->timeout_timer = NULL; 3813230557Sjimharris } 3814230557Sjimharris 3815230557Sjimharris scic_sds_port_configuration_agent_release_resource( 3816230557Sjimharris this_controller, 3817230557Sjimharris &this_controller->port_agent); 3818230557Sjimharris 3819230557Sjimharris for(index = 0; index < SCI_MAX_PORTS+1; index++) 3820230557Sjimharris { 3821230557Sjimharris port = &this_controller->port_table[index]; 3822230557Sjimharris scic_sds_port_release_resource(this_controller, port); 3823230557Sjimharris } 3824230557Sjimharris 3825230557Sjimharris for(index = 0; index < SCI_MAX_PHYS; index++) 3826230557Sjimharris { 3827230557Sjimharris phy = &this_controller->phy_table[index]; 3828230557Sjimharris scic_sds_phy_release_resource(this_controller, phy); 3829230557Sjimharris } 3830230557Sjimharris 3831230557Sjimharris return SCI_SUCCESS; 3832230557Sjimharris} 3833230557Sjimharris 3834230557Sjimharris 3835230557Sjimharris/** 3836230557Sjimharris * @brief This method process the ports configured message from port configuration 3837230557Sjimharris * agent. 3838230557Sjimharris * 3839230557Sjimharris * @param[in] this_controller This parameter specifies the core 3840230557Sjimharris * controller that its ports are configured. 3841230557Sjimharris * 3842230557Sjimharris * @return None. 3843230557Sjimharris */ 3844230557Sjimharrisvoid scic_sds_controller_port_agent_configured_ports( 3845230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller 3846230557Sjimharris) 3847230557Sjimharris{ 3848230557Sjimharris //simply transit to ready. The function below checks the controller state 3849230557Sjimharris scic_sds_controller_transition_to_ready( 3850230557Sjimharris this_controller, SCI_SUCCESS 3851230557Sjimharris ); 3852230557Sjimharris} 3853230557Sjimharris 3854230557Sjimharris 3855230557Sjimharris//****************************************************************************- 3856230557Sjimharris//* SCIC Controller Public Methods 3857230557Sjimharris//****************************************************************************- 3858230557Sjimharris 3859230557SjimharrisSCI_STATUS scic_controller_construct( 3860230557Sjimharris SCI_LIBRARY_HANDLE_T library, 3861230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 3862230557Sjimharris void * user_object 3863230557Sjimharris) 3864230557Sjimharris{ 3865230557Sjimharris SCIC_SDS_LIBRARY_T *my_library; 3866230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 3867230557Sjimharris 3868230557Sjimharris my_library = (SCIC_SDS_LIBRARY_T *)library; 3869230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 3870230557Sjimharris 3871230557Sjimharris SCIC_LOG_TRACE(( 3872230557Sjimharris sci_base_object_get_logger(library), 3873230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_INITIALIZATION, 3874230557Sjimharris "scic_controller_construct(0x%x, 0x%x) enter\n", 3875230557Sjimharris library, controller 3876230557Sjimharris )); 3877230557Sjimharris 3878230557Sjimharris // Just clear out the memory of the structure to be safe. 3879230557Sjimharris memset(this_controller, 0, sizeof(SCIC_SDS_CONTROLLER_T)); 3880230557Sjimharris 3881230557Sjimharris // Make sure that the static data is assigned before moving onto the 3882230557Sjimharris // base constroller construct as this will cause the controller to 3883230557Sjimharris // enter its initial state and the controller_index and pci_revision 3884230557Sjimharris // will be required to complete those operations correctly 3885230557Sjimharris this_controller->controller_index = 3886230557Sjimharris scic_sds_library_get_controller_index(my_library, this_controller); 3887230557Sjimharris 3888230557Sjimharris this_controller->pci_revision = my_library->pci_revision; 3889230557Sjimharris 3890230557Sjimharris sci_base_controller_construct( 3891230557Sjimharris &this_controller->parent, 3892230557Sjimharris sci_base_object_get_logger(my_library), 3893230557Sjimharris scic_sds_controller_state_table, 3894230557Sjimharris this_controller->memory_descriptors, 3895230557Sjimharris ARRAY_SIZE(this_controller->memory_descriptors), 3896230557Sjimharris NULL 3897230557Sjimharris ); 3898230557Sjimharris 3899230557Sjimharris sci_object_set_association(controller, user_object); 3900230557Sjimharris 3901230557Sjimharris scic_sds_controller_initialize_state_logging(this_controller); 3902230557Sjimharris 3903230557Sjimharris scic_sds_pci_bar_initialization(this_controller); 3904230557Sjimharris 3905230557Sjimharris return SCI_SUCCESS; 3906230557Sjimharris} 3907230557Sjimharris 3908230557Sjimharris// --------------------------------------------------------------------------- 3909230557Sjimharris 3910230557SjimharrisSCI_STATUS scic_controller_initialize( 3911230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 3912230557Sjimharris) 3913230557Sjimharris{ 3914230557Sjimharris SCI_STATUS status = SCI_FAILURE_INVALID_STATE; 3915230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 3916230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 3917230557Sjimharris 3918230557Sjimharris SCIC_LOG_TRACE(( 3919230557Sjimharris sci_base_object_get_logger(controller), 3920230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 3921230557Sjimharris "scic_controller_initialize(0x%x, 0x%d) enter\n", 3922230557Sjimharris controller 3923230557Sjimharris )); 3924230557Sjimharris 3925230557Sjimharris if (this_controller->state_handlers->parent.initialize_handler != NULL) 3926230557Sjimharris { 3927230557Sjimharris status = this_controller->state_handlers->parent.initialize_handler( 3928230557Sjimharris (SCI_BASE_CONTROLLER_T *)controller 3929230557Sjimharris ); 3930230557Sjimharris } 3931230557Sjimharris else 3932230557Sjimharris { 3933230557Sjimharris SCIC_LOG_WARNING(( 3934230557Sjimharris sci_base_object_get_logger(this_controller), 3935230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 3936230557Sjimharris "SCIC Controller initialize operation requested in invalid state %d\n", 3937230557Sjimharris sci_base_state_machine_get_state( 3938230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller)) 3939230557Sjimharris )); 3940230557Sjimharris } 3941230557Sjimharris 3942230557Sjimharris return status; 3943230557Sjimharris} 3944230557Sjimharris 3945230557Sjimharris// --------------------------------------------------------------------------- 3946230557Sjimharris 3947230557SjimharrisU32 scic_controller_get_suggested_start_timeout( 3948230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 3949230557Sjimharris) 3950230557Sjimharris{ 3951230557Sjimharris // Validate the user supplied parameters. 3952230557Sjimharris if (controller == SCI_INVALID_HANDLE) 3953230557Sjimharris return 0; 3954230557Sjimharris 3955230557Sjimharris // The suggested minimum timeout value for a controller start operation: 3956230557Sjimharris // 3957230557Sjimharris // Signature FIS Timeout 3958230557Sjimharris // + Phy Start Timeout 3959230557Sjimharris // + Number of Phy Spin Up Intervals 3960230557Sjimharris // --------------------------------- 3961230557Sjimharris // Number of milliseconds for the controller start operation. 3962230557Sjimharris // 3963230557Sjimharris // NOTE: The number of phy spin up intervals will be equivalent 3964230557Sjimharris // to the number of phys divided by the number phys allowed 3965230557Sjimharris // per interval - 1 (once OEM parameters are supported). 3966230557Sjimharris // Currently we assume only 1 phy per interval. 3967230557Sjimharris 3968230557Sjimharris return (SCIC_SDS_SIGNATURE_FIS_TIMEOUT 3969230557Sjimharris + SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT 3970230557Sjimharris + ((SCI_MAX_PHYS-1) * SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL)); 3971230557Sjimharris} 3972230557Sjimharris 3973230557Sjimharris// --------------------------------------------------------------------------- 3974230557Sjimharris 3975230557SjimharrisSCI_STATUS scic_controller_start( 3976230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 3977230557Sjimharris U32 timeout 3978230557Sjimharris) 3979230557Sjimharris{ 3980230557Sjimharris SCI_STATUS status = SCI_FAILURE_INVALID_STATE; 3981230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 3982230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 3983230557Sjimharris 3984230557Sjimharris SCIC_LOG_TRACE(( 3985230557Sjimharris sci_base_object_get_logger(controller), 3986230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 3987230557Sjimharris "scic_controller_start(0x%x, 0x%d) enter\n", 3988230557Sjimharris controller, timeout 3989230557Sjimharris )); 3990230557Sjimharris 3991230557Sjimharris if (this_controller->state_handlers->parent.start_handler != NULL) 3992230557Sjimharris { 3993230557Sjimharris status = this_controller->state_handlers->parent.start_handler( 3994230557Sjimharris (SCI_BASE_CONTROLLER_T *)controller, timeout 3995230557Sjimharris ); 3996230557Sjimharris } 3997230557Sjimharris else 3998230557Sjimharris { 3999230557Sjimharris SCIC_LOG_WARNING(( 4000230557Sjimharris sci_base_object_get_logger(this_controller), 4001230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4002230557Sjimharris "SCIC Controller start operation requested in invalid state %d\n", 4003230557Sjimharris sci_base_state_machine_get_state( 4004230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller)) 4005230557Sjimharris )); 4006230557Sjimharris } 4007230557Sjimharris 4008230557Sjimharris return status; 4009230557Sjimharris} 4010230557Sjimharris 4011230557Sjimharris// --------------------------------------------------------------------------- 4012230557Sjimharris 4013230557SjimharrisSCI_STATUS scic_controller_stop( 4014230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4015230557Sjimharris U32 timeout 4016230557Sjimharris) 4017230557Sjimharris{ 4018230557Sjimharris SCI_STATUS status = SCI_FAILURE_INVALID_STATE; 4019230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4020230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4021230557Sjimharris 4022230557Sjimharris SCIC_LOG_TRACE(( 4023230557Sjimharris sci_base_object_get_logger(controller), 4024230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4025230557Sjimharris "scic_controller_stop(0x%x, 0x%d) enter\n", 4026230557Sjimharris controller, timeout 4027230557Sjimharris )); 4028230557Sjimharris 4029230557Sjimharris if (this_controller->state_handlers->parent.stop_handler != NULL) 4030230557Sjimharris { 4031230557Sjimharris status = this_controller->state_handlers->parent.stop_handler( 4032230557Sjimharris (SCI_BASE_CONTROLLER_T *)controller, timeout 4033230557Sjimharris ); 4034230557Sjimharris } 4035230557Sjimharris else 4036230557Sjimharris { 4037230557Sjimharris SCIC_LOG_WARNING(( 4038230557Sjimharris sci_base_object_get_logger(this_controller), 4039230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4040230557Sjimharris "SCIC Controller stop operation requested in invalid state %d\n", 4041230557Sjimharris sci_base_state_machine_get_state( 4042230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller)) 4043230557Sjimharris )); 4044230557Sjimharris } 4045230557Sjimharris 4046230557Sjimharris return status; 4047230557Sjimharris} 4048230557Sjimharris 4049230557Sjimharris// --------------------------------------------------------------------------- 4050230557Sjimharris 4051230557SjimharrisSCI_STATUS scic_controller_reset( 4052230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 4053230557Sjimharris) 4054230557Sjimharris{ 4055230557Sjimharris SCI_STATUS status = SCI_FAILURE_INVALID_STATE; 4056230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4057230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4058230557Sjimharris 4059230557Sjimharris SCIC_LOG_TRACE(( 4060230557Sjimharris sci_base_object_get_logger(controller), 4061230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4062230557Sjimharris "scic_controller_reset(0x%x) enter\n", 4063230557Sjimharris controller 4064230557Sjimharris )); 4065230557Sjimharris 4066230557Sjimharris if (this_controller->state_handlers->parent.reset_handler != NULL) 4067230557Sjimharris { 4068230557Sjimharris status = this_controller->state_handlers->parent.reset_handler( 4069230557Sjimharris (SCI_BASE_CONTROLLER_T *)controller 4070230557Sjimharris ); 4071230557Sjimharris } 4072230557Sjimharris else 4073230557Sjimharris { 4074230557Sjimharris SCIC_LOG_WARNING(( 4075230557Sjimharris sci_base_object_get_logger(this_controller), 4076230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4077230557Sjimharris "SCIC Controller reset operation requested in invalid state %d\n", 4078230557Sjimharris sci_base_state_machine_get_state( 4079230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller)) 4080230557Sjimharris )); 4081230557Sjimharris } 4082230557Sjimharris 4083230557Sjimharris return status; 4084230557Sjimharris} 4085230557Sjimharris 4086230557Sjimharris// --------------------------------------------------------------------------- 4087230557Sjimharris 4088230557SjimharrisSCI_STATUS scic_controller_get_handler_methods( 4089230557Sjimharris SCIC_INTERRUPT_TYPE interrupt_type, 4090230557Sjimharris U16 message_count, 4091230557Sjimharris SCIC_CONTROLLER_HANDLER_METHODS_T *handler_methods 4092230557Sjimharris) 4093230557Sjimharris{ 4094230557Sjimharris SCI_STATUS status = SCI_FAILURE_UNSUPPORTED_MESSAGE_COUNT; 4095230557Sjimharris 4096230557Sjimharris switch (interrupt_type) 4097230557Sjimharris { 4098230557Sjimharris#if !defined(DISABLE_INTERRUPTS) 4099230557Sjimharris case SCIC_LEGACY_LINE_INTERRUPT_TYPE: 4100230557Sjimharris if (message_count == 0) 4101230557Sjimharris { 4102230557Sjimharris handler_methods[0].interrupt_handler 4103230557Sjimharris = scic_sds_controller_legacy_interrupt_handler; 4104230557Sjimharris handler_methods[0].completion_handler 4105230557Sjimharris = scic_sds_controller_legacy_completion_handler; 4106230557Sjimharris 4107230557Sjimharris status = SCI_SUCCESS; 4108230557Sjimharris } 4109230557Sjimharris break; 4110230557Sjimharris 4111230557Sjimharris case SCIC_MSIX_INTERRUPT_TYPE: 4112230557Sjimharris if (message_count == 1) 4113230557Sjimharris { 4114230557Sjimharris handler_methods[0].interrupt_handler 4115230557Sjimharris = scic_sds_controller_single_vector_interrupt_handler; 4116230557Sjimharris handler_methods[0].completion_handler 4117230557Sjimharris = scic_sds_controller_single_vector_completion_handler; 4118230557Sjimharris 4119230557Sjimharris status = SCI_SUCCESS; 4120230557Sjimharris } 4121230557Sjimharris else if (message_count == 2) 4122230557Sjimharris { 4123230557Sjimharris handler_methods[0].interrupt_handler 4124230557Sjimharris = scic_sds_controller_normal_vector_interrupt_handler; 4125230557Sjimharris handler_methods[0].completion_handler 4126230557Sjimharris = scic_sds_controller_normal_vector_completion_handler; 4127230557Sjimharris 4128230557Sjimharris handler_methods[1].interrupt_handler 4129230557Sjimharris = scic_sds_controller_error_vector_interrupt_handler; 4130230557Sjimharris handler_methods[1].completion_handler 4131230557Sjimharris = scic_sds_controller_error_vector_completion_handler; 4132230557Sjimharris 4133230557Sjimharris status = SCI_SUCCESS; 4134230557Sjimharris } 4135230557Sjimharris break; 4136230557Sjimharris#endif // !defined(DISABLE_INTERRUPTS) 4137230557Sjimharris 4138230557Sjimharris case SCIC_NO_INTERRUPTS: 4139230557Sjimharris if (message_count == 0) 4140230557Sjimharris { 4141230557Sjimharris 4142230557Sjimharris handler_methods[0].interrupt_handler 4143230557Sjimharris = scic_sds_controller_polling_interrupt_handler; 4144230557Sjimharris handler_methods[0].completion_handler 4145230557Sjimharris = scic_sds_controller_polling_completion_handler; 4146230557Sjimharris 4147230557Sjimharris status = SCI_SUCCESS; 4148230557Sjimharris } 4149230557Sjimharris break; 4150230557Sjimharris 4151230557Sjimharris default: 4152230557Sjimharris status = SCI_FAILURE_INVALID_PARAMETER_VALUE; 4153230557Sjimharris break; 4154230557Sjimharris } 4155230557Sjimharris 4156230557Sjimharris return status; 4157230557Sjimharris} 4158230557Sjimharris 4159230557Sjimharris// --------------------------------------------------------------------------- 4160230557Sjimharris 4161230557SjimharrisSCI_IO_STATUS scic_controller_start_io( 4162230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4163230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 4164230557Sjimharris SCI_IO_REQUEST_HANDLE_T io_request, 4165230557Sjimharris U16 io_tag 4166230557Sjimharris) 4167230557Sjimharris{ 4168231296Sjimharris SCI_STATUS status; 4169230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4170230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4171230557Sjimharris 4172230557Sjimharris SCIC_LOG_TRACE(( 4173230557Sjimharris sci_base_object_get_logger(controller), 4174230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4175230557Sjimharris "scic_controller_start_io(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 4176230557Sjimharris controller, remote_device, io_request, io_tag 4177230557Sjimharris )); 4178230557Sjimharris 4179230557Sjimharris status = this_controller->state_handlers->parent.start_io_handler( 4180230557Sjimharris &this_controller->parent, 4181230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T *)remote_device, 4182230557Sjimharris (SCI_BASE_REQUEST_T *)io_request, 4183230557Sjimharris io_tag 4184230557Sjimharris ); 4185230557Sjimharris 4186231296Sjimharris return (SCI_IO_STATUS)status; 4187230557Sjimharris} 4188230557Sjimharris 4189230557Sjimharris// --------------------------------------------------------------------------- 4190230557Sjimharris 4191230557SjimharrisSCI_STATUS scic_controller_terminate_request( 4192230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4193230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 4194230557Sjimharris SCI_IO_REQUEST_HANDLE_T request 4195230557Sjimharris) 4196230557Sjimharris{ 4197230557Sjimharris SCI_STATUS status; 4198230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4199230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4200230557Sjimharris 4201230557Sjimharris SCIC_LOG_TRACE(( 4202230557Sjimharris sci_base_object_get_logger(controller), 4203230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4204230557Sjimharris "scic_controller_terminate_request(0x%x, 0x%x, 0x%x) enter\n", 4205230557Sjimharris controller, remote_device, request 4206230557Sjimharris )); 4207230557Sjimharris 4208230557Sjimharris status = this_controller->state_handlers->terminate_request_handler( 4209230557Sjimharris &this_controller->parent, 4210230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T *)remote_device, 4211230557Sjimharris (SCI_BASE_REQUEST_T *)request 4212230557Sjimharris ); 4213230557Sjimharris 4214230557Sjimharris return status; 4215230557Sjimharris} 4216230557Sjimharris 4217230557Sjimharris// --------------------------------------------------------------------------- 4218230557Sjimharris 4219230557SjimharrisSCI_STATUS scic_controller_complete_io( 4220230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4221230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 4222230557Sjimharris SCI_IO_REQUEST_HANDLE_T io_request 4223230557Sjimharris) 4224230557Sjimharris{ 4225230557Sjimharris SCI_STATUS status; 4226230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4227230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4228230557Sjimharris 4229230557Sjimharris SCIC_LOG_TRACE(( 4230230557Sjimharris sci_base_object_get_logger(controller), 4231230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4232230557Sjimharris "scic_controller_complete_io(0x%x, 0x%x, 0x%x) enter\n", 4233230557Sjimharris controller, remote_device, io_request 4234230557Sjimharris )); 4235230557Sjimharris 4236230557Sjimharris status = this_controller->state_handlers->parent.complete_io_handler( 4237230557Sjimharris &this_controller->parent, 4238230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T *)remote_device, 4239230557Sjimharris (SCI_BASE_REQUEST_T *)io_request 4240230557Sjimharris ); 4241230557Sjimharris 4242230557Sjimharris return status; 4243230557Sjimharris} 4244230557Sjimharris 4245230557Sjimharris// --------------------------------------------------------------------------- 4246230557Sjimharris 4247230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT) 4248230557Sjimharris 4249230557SjimharrisSCI_TASK_STATUS scic_controller_start_task( 4250230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4251230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 4252230557Sjimharris SCI_TASK_REQUEST_HANDLE_T task_request, 4253230557Sjimharris U16 task_tag 4254230557Sjimharris) 4255230557Sjimharris{ 4256231296Sjimharris SCI_STATUS status = SCI_FAILURE_INVALID_STATE; 4257230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4258230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4259230557Sjimharris 4260230557Sjimharris SCIC_LOG_TRACE(( 4261230557Sjimharris sci_base_object_get_logger(controller), 4262230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4263230557Sjimharris "scic_controller_start_task(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 4264230557Sjimharris controller, remote_device, task_request, task_tag 4265230557Sjimharris )); 4266230557Sjimharris 4267230557Sjimharris if (this_controller->state_handlers->parent.start_task_handler != NULL) 4268230557Sjimharris { 4269230557Sjimharris status = this_controller->state_handlers->parent.start_task_handler( 4270230557Sjimharris &this_controller->parent, 4271230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T *)remote_device, 4272230557Sjimharris (SCI_BASE_REQUEST_T *)task_request, 4273230557Sjimharris task_tag 4274230557Sjimharris ); 4275230557Sjimharris } 4276230557Sjimharris else 4277230557Sjimharris { 4278230557Sjimharris SCIC_LOG_INFO(( 4279230557Sjimharris sci_base_object_get_logger(controller), 4280230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4281230557Sjimharris "SCIC Controller starting task from invalid state\n" 4282230557Sjimharris )); 4283230557Sjimharris } 4284230557Sjimharris 4285231296Sjimharris return (SCI_TASK_STATUS)status; 4286230557Sjimharris} 4287230557Sjimharris 4288230557Sjimharris// --------------------------------------------------------------------------- 4289230557Sjimharris 4290230557SjimharrisSCI_STATUS scic_controller_complete_task( 4291230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4292230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 4293230557Sjimharris SCI_TASK_REQUEST_HANDLE_T task_request 4294230557Sjimharris) 4295230557Sjimharris{ 4296230557Sjimharris SCI_STATUS status = SCI_FAILURE_INVALID_STATE; 4297230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4298230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4299230557Sjimharris 4300230557Sjimharris SCIC_LOG_TRACE(( 4301230557Sjimharris sci_base_object_get_logger(controller), 4302230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4303230557Sjimharris "scic_controller_complete_task(0x%x, 0x%x, 0x%x) enter\n", 4304230557Sjimharris controller, remote_device, task_request 4305230557Sjimharris )); 4306230557Sjimharris 4307230557Sjimharris if (this_controller->state_handlers->parent.complete_task_handler != NULL) 4308230557Sjimharris { 4309230557Sjimharris status = this_controller->state_handlers->parent.complete_task_handler( 4310230557Sjimharris &this_controller->parent, 4311230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T *)remote_device, 4312230557Sjimharris (SCI_BASE_REQUEST_T *)task_request 4313230557Sjimharris ); 4314230557Sjimharris } 4315230557Sjimharris else 4316230557Sjimharris { 4317230557Sjimharris SCIC_LOG_INFO(( 4318230557Sjimharris sci_base_object_get_logger(controller), 4319230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4320230557Sjimharris "SCIC Controller completing task from invalid state\n" 4321230557Sjimharris )); 4322230557Sjimharris } 4323230557Sjimharris 4324230557Sjimharris return status; 4325230557Sjimharris} 4326230557Sjimharris 4327230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT) 4328230557Sjimharris 4329230557Sjimharris// --------------------------------------------------------------------------- 4330230557Sjimharris 4331230557SjimharrisSCI_STATUS scic_controller_get_port_handle( 4332230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4333230557Sjimharris U8 port_index, 4334230557Sjimharris SCI_PORT_HANDLE_T * port_handle 4335230557Sjimharris) 4336230557Sjimharris{ 4337230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4338230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4339230557Sjimharris 4340230557Sjimharris SCIC_LOG_TRACE(( 4341230557Sjimharris sci_base_object_get_logger(controller), 4342230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4343230557Sjimharris "scic_controller_get_port_handle(0x%x, 0x%x, 0x%x) enter\n", 4344230557Sjimharris controller, port_index, port_handle 4345230557Sjimharris )); 4346230557Sjimharris 4347230557Sjimharris if (port_index < this_controller->logical_port_entries) 4348230557Sjimharris { 4349230557Sjimharris *port_handle = &this_controller->port_table[port_index]; 4350230557Sjimharris 4351230557Sjimharris return SCI_SUCCESS; 4352230557Sjimharris } 4353230557Sjimharris 4354230557Sjimharris return SCI_FAILURE_INVALID_PORT; 4355230557Sjimharris} 4356230557Sjimharris 4357230557Sjimharris// --------------------------------------------------------------------------- 4358230557Sjimharris 4359230557SjimharrisSCI_STATUS scic_controller_get_phy_handle( 4360230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4361230557Sjimharris U8 phy_index, 4362230557Sjimharris SCI_PHY_HANDLE_T * phy_handle 4363230557Sjimharris) 4364230557Sjimharris{ 4365230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4366230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4367230557Sjimharris 4368230557Sjimharris SCIC_LOG_TRACE(( 4369230557Sjimharris sci_base_object_get_logger(controller), 4370230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4371230557Sjimharris "scic_controller_get_phy_handle(0x%x, 0x%x, 0x%x) enter\n", 4372230557Sjimharris controller, phy_index, phy_handle 4373230557Sjimharris )); 4374230557Sjimharris 4375230557Sjimharris if (phy_index < ARRAY_SIZE(this_controller->phy_table)) 4376230557Sjimharris { 4377230557Sjimharris *phy_handle = &this_controller->phy_table[phy_index]; 4378230557Sjimharris 4379230557Sjimharris return SCI_SUCCESS; 4380230557Sjimharris } 4381230557Sjimharris 4382230557Sjimharris SCIC_LOG_ERROR(( 4383230557Sjimharris sci_base_object_get_logger(this_controller), 4384230557Sjimharris SCIC_LOG_OBJECT_PORT | SCIC_LOG_OBJECT_CONTROLLER, 4385230557Sjimharris "Controller:0x%x PhyId:0x%x invalid phy index\n", 4386230557Sjimharris this_controller, phy_index 4387230557Sjimharris )); 4388230557Sjimharris 4389230557Sjimharris return SCI_FAILURE_INVALID_PHY; 4390230557Sjimharris} 4391230557Sjimharris 4392230557Sjimharris// --------------------------------------------------------------------------- 4393230557Sjimharris 4394230557SjimharrisU16 scic_controller_allocate_io_tag( 4395230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 4396230557Sjimharris) 4397230557Sjimharris{ 4398230557Sjimharris U16 task_context; 4399230557Sjimharris U16 sequence_count; 4400230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4401230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4402230557Sjimharris 4403230557Sjimharris SCIC_LOG_TRACE(( 4404230557Sjimharris sci_base_object_get_logger(controller), 4405230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4406230557Sjimharris "scic_controller_allocate_io_tag(0x%x) enter\n", 4407230557Sjimharris controller 4408230557Sjimharris )); 4409230557Sjimharris 4410230557Sjimharris if (!sci_pool_empty(this_controller->tci_pool)) 4411230557Sjimharris { 4412230557Sjimharris sci_pool_get(this_controller->tci_pool, task_context); 4413230557Sjimharris 4414230557Sjimharris sequence_count = this_controller->io_request_sequence[task_context]; 4415230557Sjimharris 4416230557Sjimharris return scic_sds_io_tag_construct(sequence_count, task_context); 4417230557Sjimharris } 4418230557Sjimharris 4419230557Sjimharris return SCI_CONTROLLER_INVALID_IO_TAG; 4420230557Sjimharris} 4421230557Sjimharris 4422230557Sjimharris// --------------------------------------------------------------------------- 4423230557Sjimharris 4424230557SjimharrisSCI_STATUS scic_controller_free_io_tag( 4425230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4426230557Sjimharris U16 io_tag 4427230557Sjimharris) 4428230557Sjimharris{ 4429230557Sjimharris U16 sequence; 4430230557Sjimharris U16 index; 4431230557Sjimharris 4432230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4433230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4434230557Sjimharris 4435230557Sjimharris ASSERT(io_tag != SCI_CONTROLLER_INVALID_IO_TAG); 4436230557Sjimharris 4437230557Sjimharris SCIC_LOG_TRACE(( 4438230557Sjimharris sci_base_object_get_logger(controller), 4439230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4440230557Sjimharris "scic_controller_free_io_tag(0x%x, 0x%x) enter\n", 4441230557Sjimharris controller, io_tag 4442230557Sjimharris )); 4443230557Sjimharris 4444230557Sjimharris sequence = scic_sds_io_tag_get_sequence(io_tag); 4445230557Sjimharris index = scic_sds_io_tag_get_index(io_tag); 4446230557Sjimharris 4447230557Sjimharris if (!sci_pool_full(this_controller->tci_pool)) 4448230557Sjimharris { 4449230557Sjimharris if (sequence == this_controller->io_request_sequence[index]) 4450230557Sjimharris { 4451230557Sjimharris scic_sds_io_sequence_increment( 4452230557Sjimharris this_controller->io_request_sequence[index]); 4453230557Sjimharris 4454230557Sjimharris sci_pool_put(this_controller->tci_pool, index); 4455230557Sjimharris 4456230557Sjimharris return SCI_SUCCESS; 4457230557Sjimharris } 4458230557Sjimharris } 4459230557Sjimharris 4460230557Sjimharris return SCI_FAILURE_INVALID_IO_TAG; 4461230557Sjimharris} 4462230557Sjimharris 4463230557Sjimharris// --------------------------------------------------------------------------- 4464230557Sjimharris 4465230557Sjimharrisvoid scic_controller_enable_interrupts( 4466230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 4467230557Sjimharris) 4468230557Sjimharris{ 4469230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4470230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4471230557Sjimharris 4472230557Sjimharris ASSERT(this_controller->smu_registers != NULL); 4473230557Sjimharris 4474230557Sjimharris SMU_IMR_WRITE(this_controller, 0x00000000); 4475230557Sjimharris} 4476230557Sjimharris 4477230557Sjimharris// --------------------------------------------------------------------------- 4478230557Sjimharris 4479230557Sjimharrisvoid scic_controller_disable_interrupts( 4480230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 4481230557Sjimharris) 4482230557Sjimharris{ 4483230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 4484230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4485230557Sjimharris 4486230557Sjimharris ASSERT(this_controller->smu_registers != NULL); 4487230557Sjimharris 4488230557Sjimharris SMU_IMR_WRITE(this_controller, 0xffffffff); 4489230557Sjimharris} 4490230557Sjimharris 4491230557Sjimharris// --------------------------------------------------------------------------- 4492230557Sjimharris 4493230557SjimharrisSCI_STATUS scic_controller_set_mode( 4494230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4495230557Sjimharris SCI_CONTROLLER_MODE operating_mode 4496230557Sjimharris) 4497230557Sjimharris{ 4498230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 4499230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 4500230557Sjimharris 4501230557Sjimharris SCIC_LOG_TRACE(( 4502230557Sjimharris sci_base_object_get_logger(controller), 4503230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 4504230557Sjimharris "scic_controller_set_mode(0x%x, 0x%x) enter\n", 4505230557Sjimharris controller, operating_mode 4506230557Sjimharris )); 4507230557Sjimharris 4508230557Sjimharris if ( 4509230557Sjimharris (this_controller->parent.state_machine.current_state_id 4510230557Sjimharris == SCI_BASE_CONTROLLER_STATE_INITIALIZING) 4511230557Sjimharris || (this_controller->parent.state_machine.current_state_id 4512230557Sjimharris == SCI_BASE_CONTROLLER_STATE_INITIALIZED) 4513230557Sjimharris ) 4514230557Sjimharris { 4515230557Sjimharris switch (operating_mode) 4516230557Sjimharris { 4517230557Sjimharris case SCI_MODE_SPEED: 4518230557Sjimharris this_controller->remote_node_entries = 4519230557Sjimharris MIN(this_controller->remote_node_entries, SCI_MAX_REMOTE_DEVICES); 4520230557Sjimharris this_controller->task_context_entries = 4521230557Sjimharris MIN(this_controller->task_context_entries, SCU_IO_REQUEST_COUNT); 4522230557Sjimharris this_controller->uf_control.buffers.count = 4523230557Sjimharris MIN(this_controller->uf_control.buffers.count, SCU_UNSOLICITED_FRAME_COUNT); 4524230557Sjimharris this_controller->completion_event_entries = 4525230557Sjimharris MIN(this_controller->completion_event_entries, SCU_EVENT_COUNT); 4526230557Sjimharris this_controller->completion_queue_entries = 4527230557Sjimharris MIN(this_controller->completion_queue_entries, SCU_COMPLETION_QUEUE_COUNT); 4528230557Sjimharris 4529230557Sjimharris scic_sds_controller_build_memory_descriptor_table(this_controller); 4530230557Sjimharris break; 4531230557Sjimharris 4532230557Sjimharris case SCI_MODE_SIZE: 4533230557Sjimharris this_controller->remote_node_entries = 4534230557Sjimharris MIN(this_controller->remote_node_entries, SCI_MIN_REMOTE_DEVICES); 4535230557Sjimharris this_controller->task_context_entries = 4536230557Sjimharris MIN(this_controller->task_context_entries, SCI_MIN_IO_REQUESTS); 4537230557Sjimharris this_controller->uf_control.buffers.count = 4538230557Sjimharris MIN(this_controller->uf_control.buffers.count, SCU_MIN_UNSOLICITED_FRAMES); 4539230557Sjimharris this_controller->completion_event_entries = 4540230557Sjimharris MIN(this_controller->completion_event_entries, SCU_MIN_EVENTS); 4541230557Sjimharris this_controller->completion_queue_entries = 4542230557Sjimharris MIN(this_controller->completion_queue_entries, SCU_MIN_COMPLETION_QUEUE_ENTRIES); 4543230557Sjimharris 4544230557Sjimharris scic_sds_controller_build_memory_descriptor_table(this_controller); 4545230557Sjimharris break; 4546230557Sjimharris 4547230557Sjimharris default: 4548230557Sjimharris status = SCI_FAILURE_INVALID_PARAMETER_VALUE; 4549230557Sjimharris break; 4550230557Sjimharris } 4551230557Sjimharris } 4552230557Sjimharris else 4553230557Sjimharris status = SCI_FAILURE_INVALID_STATE; 4554230557Sjimharris 4555230557Sjimharris return status; 4556230557Sjimharris} 4557230557Sjimharris 4558230557Sjimharris/** 4559230557Sjimharris * This method will reset the controller hardware. 4560230557Sjimharris * 4561230557Sjimharris * @param[in] this_controller The controller that is to be reset. 4562230557Sjimharris */ 4563230557Sjimharrisvoid scic_sds_controller_reset_hardware( 4564230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller 4565230557Sjimharris) 4566230557Sjimharris{ 4567230557Sjimharris // Disable interrupts so we dont take any spurious interrupts 4568230557Sjimharris scic_controller_disable_interrupts(this_controller); 4569230557Sjimharris 4570230557Sjimharris // Reset the SCU 4571230557Sjimharris SMU_SMUSRCR_WRITE(this_controller, 0xFFFFFFFF); 4572230557Sjimharris 4573230557Sjimharris // Delay for 1ms to before clearing the CQP and UFQPR. 4574230557Sjimharris scic_cb_stall_execution(1000); 4575230557Sjimharris 4576230557Sjimharris // The write to the CQGR clears the CQP 4577230557Sjimharris SMU_CQGR_WRITE(this_controller, 0x00000000); 4578230557Sjimharris 4579230557Sjimharris // The write to the UFQGP clears the UFQPR 4580230557Sjimharris SCU_UFQGP_WRITE(this_controller, 0x00000000); 4581230557Sjimharris} 4582230557Sjimharris 4583230557Sjimharris// --------------------------------------------------------------------------- 4584230557Sjimharris 4585230557SjimharrisSCI_STATUS scic_user_parameters_set( 4586230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4587230557Sjimharris SCIC_USER_PARAMETERS_T * scic_parms 4588230557Sjimharris) 4589230557Sjimharris{ 4590230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 4591230557Sjimharris 4592230557Sjimharris if ( 4593230557Sjimharris (this_controller->parent.state_machine.current_state_id 4594230557Sjimharris == SCI_BASE_CONTROLLER_STATE_RESET) 4595230557Sjimharris || (this_controller->parent.state_machine.current_state_id 4596230557Sjimharris == SCI_BASE_CONTROLLER_STATE_INITIALIZING) 4597230557Sjimharris || (this_controller->parent.state_machine.current_state_id 4598230557Sjimharris == SCI_BASE_CONTROLLER_STATE_INITIALIZED) 4599230557Sjimharris ) 4600230557Sjimharris { 4601230557Sjimharris U16 index; 4602230557Sjimharris 4603230557Sjimharris // Validate the user parameters. If they are not legal, then 4604230557Sjimharris // return a failure. 4605230557Sjimharris for (index = 0; index < SCI_MAX_PHYS; index++) 4606230557Sjimharris { 4607230557Sjimharris if (! 4608230557Sjimharris ( scic_parms->sds1.phys[index].max_speed_generation 4609230557Sjimharris <= SCIC_SDS_PARM_MAX_SPEED 4610230557Sjimharris && scic_parms->sds1.phys[index].max_speed_generation 4611230557Sjimharris > SCIC_SDS_PARM_NO_SPEED 4612230557Sjimharris ) 4613230557Sjimharris ) 4614230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4615230557Sjimharris 4616230557Sjimharris if ( 4617230557Sjimharris (scic_parms->sds1.phys[index].in_connection_align_insertion_frequency < 3) || 4618230557Sjimharris (scic_parms->sds1.phys[index].align_insertion_frequency == 0) || 4619230557Sjimharris (scic_parms->sds1.phys[index].notify_enable_spin_up_insertion_frequency == 0) 4620230557Sjimharris ) 4621230557Sjimharris { 4622230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4623230557Sjimharris } 4624230557Sjimharris } 4625230557Sjimharris 4626230557Sjimharris if ( 4627230557Sjimharris (scic_parms->sds1.stp_inactivity_timeout == 0) || 4628230557Sjimharris (scic_parms->sds1.ssp_inactivity_timeout == 0) || 4629230557Sjimharris (scic_parms->sds1.stp_max_occupancy_timeout == 0) || 4630230557Sjimharris (scic_parms->sds1.ssp_max_occupancy_timeout == 0) || 4631230557Sjimharris (scic_parms->sds1.no_outbound_task_timeout == 0) 4632230557Sjimharris ) 4633230557Sjimharris { 4634230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4635230557Sjimharris } 4636230557Sjimharris 4637230557Sjimharris memcpy( 4638230557Sjimharris (&this_controller->user_parameters), scic_parms, sizeof(*scic_parms)); 4639230557Sjimharris 4640230557Sjimharris return SCI_SUCCESS; 4641230557Sjimharris } 4642230557Sjimharris 4643230557Sjimharris return SCI_FAILURE_INVALID_STATE; 4644230557Sjimharris} 4645230557Sjimharris 4646230557Sjimharris// --------------------------------------------------------------------------- 4647230557Sjimharris 4648230557Sjimharrisvoid scic_user_parameters_get( 4649230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4650230557Sjimharris SCIC_USER_PARAMETERS_T * scic_parms 4651230557Sjimharris) 4652230557Sjimharris{ 4653230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 4654230557Sjimharris 4655230557Sjimharris memcpy(scic_parms, (&this_controller->user_parameters), sizeof(*scic_parms)); 4656230557Sjimharris} 4657230557Sjimharris 4658230557Sjimharris// --------------------------------------------------------------------------- 4659230557SjimharrisSCI_STATUS scic_oem_parameters_set( 4660230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4661230557Sjimharris SCIC_OEM_PARAMETERS_T * scic_parms, 4662230557Sjimharris U8 scic_parms_version 4663230557Sjimharris) 4664230557Sjimharris{ 4665230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 4666230557Sjimharris SCI_BIOS_OEM_PARAM_ELEMENT_T *old_oem_params = 4667230557Sjimharris (SCI_BIOS_OEM_PARAM_ELEMENT_T *)(&(scic_parms->sds1)); 4668230557Sjimharris 4669230557Sjimharris 4670230557Sjimharris if ( 4671230557Sjimharris (this_controller->parent.state_machine.current_state_id 4672230557Sjimharris == SCI_BASE_CONTROLLER_STATE_RESET) 4673230557Sjimharris || (this_controller->parent.state_machine.current_state_id 4674230557Sjimharris == SCI_BASE_CONTROLLER_STATE_INITIALIZING) 4675230557Sjimharris || (this_controller->parent.state_machine.current_state_id 4676230557Sjimharris == SCI_BASE_CONTROLLER_STATE_INITIALIZED) 4677230557Sjimharris ) 4678230557Sjimharris { 4679230557Sjimharris U16 index; 4680230557Sjimharris U8 combined_phy_mask = 0; 4681230557Sjimharris 4682230557Sjimharris /* 4683230557Sjimharris * Set the OEM parameter version for the controller. This comes 4684230557Sjimharris * from the OEM parameter block header or the registry depending 4685230557Sjimharris * on what WCDL is set to retrieve. 4686230557Sjimharris */ 4687230557Sjimharris this_controller->oem_parameters_version = scic_parms_version; 4688230557Sjimharris 4689230557Sjimharris // Validate the oem parameters. If they are not legal, then 4690230557Sjimharris // return a failure. 4691230557Sjimharris for(index=0; index<SCI_MAX_PORTS; index++) 4692230557Sjimharris { 4693230557Sjimharris if (scic_parms->sds1.ports[index].phy_mask > SCIC_SDS_PARM_PHY_MASK_MAX) 4694230557Sjimharris { 4695230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4696230557Sjimharris } 4697230557Sjimharris } 4698230557Sjimharris 4699230557Sjimharris for(index=0; index<SCI_MAX_PHYS; index++) 4700230557Sjimharris { 4701230557Sjimharris if ( 4702230557Sjimharris scic_parms->sds1.phys[index].sas_address.sci_format.high == 0 4703230557Sjimharris && scic_parms->sds1.phys[index].sas_address.sci_format.low == 0 4704230557Sjimharris ) 4705230557Sjimharris { 4706230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4707230557Sjimharris } 4708230557Sjimharris 4709230557Sjimharris#if defined(PBG_HBA_A0_BUILD) || defined(PBG_HBA_A2_BUILD) || defined(PBG_HBA_BETA_BUILD) || defined(PBG_BUILD) 4710230557Sjimharris if ( 4711230557Sjimharris (scic_parms->sds1.phys[index].afe_tx_amp_control0 == 0) || 4712230557Sjimharris (scic_parms->sds1.phys[index].afe_tx_amp_control1 == 0) || 4713230557Sjimharris (scic_parms->sds1.phys[index].afe_tx_amp_control2 == 0) || 4714230557Sjimharris (scic_parms->sds1.phys[index].afe_tx_amp_control3 == 0) 4715230557Sjimharris ) 4716230557Sjimharris { 4717230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4718230557Sjimharris } 4719230557Sjimharris#endif 4720230557Sjimharris } 4721230557Sjimharris 4722230557Sjimharris if (scic_parms->sds1.controller.mode_type == SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE) 4723230557Sjimharris { 4724230557Sjimharris for(index=0; index<SCI_MAX_PHYS; index++) 4725230557Sjimharris { 4726230557Sjimharris if (scic_parms->sds1.ports[index].phy_mask != 0) 4727230557Sjimharris { 4728230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4729230557Sjimharris } 4730230557Sjimharris } 4731230557Sjimharris } 4732230557Sjimharris else if (scic_parms->sds1.controller.mode_type == SCIC_PORT_MANUAL_CONFIGURATION_MODE) 4733230557Sjimharris { 4734230557Sjimharris for(index=0; index<SCI_MAX_PHYS; index++) 4735230557Sjimharris { 4736230557Sjimharris combined_phy_mask |= scic_parms->sds1.ports[index].phy_mask; 4737230557Sjimharris } 4738230557Sjimharris 4739230557Sjimharris if (combined_phy_mask == 0) 4740230557Sjimharris { 4741230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4742230557Sjimharris } 4743230557Sjimharris } 4744230557Sjimharris else 4745230557Sjimharris { 4746230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4747230557Sjimharris } 4748230557Sjimharris 4749230557Sjimharris if (scic_parms->sds1.controller.max_number_concurrent_device_spin_up > MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT) 4750230557Sjimharris { 4751230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4752230557Sjimharris } 4753230557Sjimharris 4754230557Sjimharris if (old_oem_params->controller.do_enable_ssc != 0) 4755230557Sjimharris { 4756230557Sjimharris if ( (scic_parms_version == SCI_OEM_PARAM_VER_1_0) 4757230557Sjimharris && (old_oem_params->controller.do_enable_ssc != 0x01)) 4758230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4759230557Sjimharris 4760230557Sjimharris if (scic_parms_version >= SCI_OEM_PARAM_VER_1_1) 4761230557Sjimharris { 4762230557Sjimharris SCI_BIOS_OEM_PARAM_ELEMENT_v_1_1_T *oem_params = 4763230557Sjimharris (SCI_BIOS_OEM_PARAM_ELEMENT_v_1_1_T*)(&(scic_parms->sds1)); 4764230557Sjimharris 4765230557Sjimharris U8 test = oem_params->controller.ssc_sata_tx_spread_level; 4766230557Sjimharris if ( !((test == 0x0) || (test == 0x2) || (test == 0x3) || 4767230557Sjimharris (test == 0x6) || (test == 0x7)) ) 4768230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4769230557Sjimharris 4770230557Sjimharris test = oem_params->controller.ssc_sas_tx_spread_level; 4771230557Sjimharris if (oem_params->controller.ssc_sas_tx_type == 0) 4772230557Sjimharris { 4773230557Sjimharris if ( !((test == 0x0) || (test == 0x2) || (test == 0x3)) ) 4774230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4775230557Sjimharris } 4776230557Sjimharris else 4777230557Sjimharris if (oem_params->controller.ssc_sas_tx_type == 1) 4778230557Sjimharris { 4779230557Sjimharris if ( !((test == 0x0) || (test == 0x3) || (test == 0x6)) ) 4780230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4781230557Sjimharris } 4782230557Sjimharris } 4783230557Sjimharris } 4784230557Sjimharris 4785230557Sjimharris memcpy( 4786230557Sjimharris (&this_controller->oem_parameters), scic_parms, sizeof(*scic_parms)); 4787230557Sjimharris return SCI_SUCCESS; 4788230557Sjimharris } 4789230557Sjimharris 4790230557Sjimharris return SCI_FAILURE_INVALID_STATE; 4791230557Sjimharris} 4792230557Sjimharris 4793230557Sjimharris// --------------------------------------------------------------------------- 4794230557Sjimharris 4795230557Sjimharrisvoid scic_oem_parameters_get( 4796230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4797230557Sjimharris SCIC_OEM_PARAMETERS_T * scic_parms 4798230557Sjimharris) 4799230557Sjimharris{ 4800230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 4801230557Sjimharris 4802230557Sjimharris memcpy(scic_parms, (&this_controller->oem_parameters), sizeof(*scic_parms)); 4803230557Sjimharris} 4804230557Sjimharris 4805230557Sjimharris// --------------------------------------------------------------------------- 4806230557Sjimharris 4807230557Sjimharris#if !defined(DISABLE_INTERRUPTS) 4808230557Sjimharris 4809230557Sjimharris#define INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_LOWER_BOUND_NS 853 4810230557Sjimharris#define INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_UPPER_BOUND_NS 1280 4811230557Sjimharris#define INTERRUPT_COALESCE_TIMEOUT_MAX_US 2700000 4812230557Sjimharris#define INTERRUPT_COALESCE_NUMBER_MAX 256 4813230557Sjimharris#define INTERRUPT_COALESCE_TIMEOUT_ENCODE_MIN 7 4814230557Sjimharris#define INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX 28 4815230557Sjimharris 4816230557SjimharrisSCI_STATUS scic_controller_set_interrupt_coalescence( 4817230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4818230557Sjimharris U32 coalesce_number, 4819230557Sjimharris U32 coalesce_timeout 4820230557Sjimharris) 4821230557Sjimharris{ 4822230557Sjimharris SCIC_SDS_CONTROLLER_T * scic_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4823230557Sjimharris U8 timeout_encode = 0; 4824230557Sjimharris U32 min = 0; 4825230557Sjimharris U32 max = 0; 4826230557Sjimharris 4827230557Sjimharris //Check if the input parameters fall in the range. 4828230557Sjimharris if (coalesce_number > INTERRUPT_COALESCE_NUMBER_MAX) 4829230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4830230557Sjimharris 4831230557Sjimharris // Defined encoding for interrupt coalescing timeout: 4832230557Sjimharris // Value Min Max Units 4833230557Sjimharris // ----- --- --- ----- 4834230557Sjimharris // 0 - - Disabled 4835230557Sjimharris // 1 13.3 20.0 ns 4836230557Sjimharris // 2 26.7 40.0 4837230557Sjimharris // 3 53.3 80.0 4838230557Sjimharris // 4 106.7 160.0 4839230557Sjimharris // 5 213.3 320.0 4840230557Sjimharris // 6 426.7 640.0 4841230557Sjimharris // 7 853.3 1280.0 4842230557Sjimharris // 8 1.7 2.6 us 4843230557Sjimharris // 9 3.4 5.1 4844230557Sjimharris // 10 6.8 10.2 4845230557Sjimharris // 11 13.7 20.5 4846230557Sjimharris // 12 27.3 41.0 4847230557Sjimharris // 13 54.6 81.9 4848230557Sjimharris // 14 109.2 163.8 4849230557Sjimharris // 15 218.5 327.7 4850230557Sjimharris // 16 436.9 655.4 4851230557Sjimharris // 17 873.8 1310.7 4852230557Sjimharris // 18 1.7 2.6 ms 4853230557Sjimharris // 19 3.5 5.2 4854230557Sjimharris // 20 7.0 10.5 4855230557Sjimharris // 21 14.0 21.0 4856230557Sjimharris // 22 28.0 41.9 4857230557Sjimharris // 23 55.9 83.9 4858230557Sjimharris // 24 111.8 167.8 4859230557Sjimharris // 25 223.7 335.5 4860230557Sjimharris // 26 447.4 671.1 4861230557Sjimharris // 27 894.8 1342.2 4862230557Sjimharris // 28 1.8 2.7 s 4863230557Sjimharris // Others Undefined 4864230557Sjimharris 4865230557Sjimharris //Use the table above to decide the encode of interrupt coalescing timeout 4866230557Sjimharris //value for register writing. 4867230557Sjimharris if (coalesce_timeout == 0) 4868230557Sjimharris timeout_encode = 0; 4869230557Sjimharris else 4870230557Sjimharris { 4871230557Sjimharris //make the timeout value in unit of (10 ns). 4872230557Sjimharris coalesce_timeout = coalesce_timeout * 100; 4873230557Sjimharris min = INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_LOWER_BOUND_NS / 10; 4874230557Sjimharris max = INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_UPPER_BOUND_NS / 10; 4875230557Sjimharris 4876230557Sjimharris //get the encode of timeout for register writing. 4877230557Sjimharris for ( timeout_encode = INTERRUPT_COALESCE_TIMEOUT_ENCODE_MIN; 4878230557Sjimharris timeout_encode <= INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX; 4879230557Sjimharris timeout_encode++ ) 4880230557Sjimharris { 4881230557Sjimharris if (min <= coalesce_timeout && max > coalesce_timeout) 4882230557Sjimharris break; 4883230557Sjimharris else if (coalesce_timeout >= max && coalesce_timeout < min*2 4884230557Sjimharris && coalesce_timeout <= INTERRUPT_COALESCE_TIMEOUT_MAX_US*100) 4885230557Sjimharris { 4886230557Sjimharris if ( (coalesce_timeout-max) < (2*min - coalesce_timeout) ) 4887230557Sjimharris break; 4888230557Sjimharris else 4889230557Sjimharris { 4890230557Sjimharris timeout_encode++; 4891230557Sjimharris break; 4892230557Sjimharris } 4893230557Sjimharris } 4894230557Sjimharris else 4895230557Sjimharris { 4896230557Sjimharris max = max*2; 4897230557Sjimharris min = min*2; 4898230557Sjimharris } 4899230557Sjimharris } 4900230557Sjimharris 4901230557Sjimharris if ( timeout_encode == INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX+1 ) 4902230557Sjimharris //the value is out of range. 4903230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4904230557Sjimharris } 4905230557Sjimharris 4906230557Sjimharris SMU_ICC_WRITE( 4907230557Sjimharris scic_controller, 4908230557Sjimharris (SMU_ICC_GEN_VAL(NUMBER, coalesce_number)| 4909230557Sjimharris SMU_ICC_GEN_VAL(TIMER, timeout_encode)) 4910230557Sjimharris ); 4911230557Sjimharris 4912230557Sjimharris scic_controller->interrupt_coalesce_number = (U16)coalesce_number; 4913230557Sjimharris scic_controller->interrupt_coalesce_timeout = coalesce_timeout/100; 4914230557Sjimharris 4915230557Sjimharris return SCI_SUCCESS; 4916230557Sjimharris} 4917230557Sjimharris 4918230557Sjimharris// --------------------------------------------------------------------------- 4919230557Sjimharris 4920230557Sjimharrisvoid scic_controller_get_interrupt_coalescence( 4921230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4922230557Sjimharris U32 * coalesce_number, 4923230557Sjimharris U32 * coalesce_timeout 4924230557Sjimharris) 4925230557Sjimharris{ 4926230557Sjimharris SCIC_SDS_CONTROLLER_T * scic_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4927230557Sjimharris *coalesce_number = scic_controller->interrupt_coalesce_number; 4928230557Sjimharris *coalesce_timeout = scic_controller->interrupt_coalesce_timeout; 4929230557Sjimharris} 4930230557Sjimharris 4931230557Sjimharris#endif // !defined(DISABLE_INTERRUPTS) 4932230557Sjimharris 4933230557Sjimharris// --------------------------------------------------------------------------- 4934230557Sjimharris 4935230557SjimharrisU32 scic_controller_get_scratch_ram_size( 4936230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 4937230557Sjimharris) 4938230557Sjimharris{ 4939230557Sjimharris return SCU_SCRATCH_RAM_SIZE_IN_DWORDS; 4940230557Sjimharris} 4941230557Sjimharris 4942230557Sjimharris// --------------------------------------------------------------------------- 4943230557Sjimharris 4944230557SjimharrisSCI_STATUS scic_controller_read_scratch_ram_dword( 4945230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4946230557Sjimharris U32 offset, 4947230557Sjimharris U32 * value 4948230557Sjimharris) 4949230557Sjimharris{ 4950230557Sjimharris U32 zpt_index; 4951230557Sjimharris SCIC_SDS_CONTROLLER_T * scic_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4952230557Sjimharris U32 status = SMU_SMUCSR_READ(scic_controller); 4953230557Sjimharris 4954230557Sjimharris //Check if the SCU Scratch RAM been initialized, if not return zeros 4955230557Sjimharris if ((status & SCU_RAM_INIT_COMPLETED) != SCU_RAM_INIT_COMPLETED) 4956230557Sjimharris { 4957230557Sjimharris *value = 0x00000000; 4958230557Sjimharris return SCI_SUCCESS; 4959230557Sjimharris } 4960230557Sjimharris 4961230557Sjimharris if (offset < scic_controller_get_scratch_ram_size(controller)) 4962230557Sjimharris { 4963230557Sjimharris if(offset <= SCU_MAX_ZPT_DWORD_INDEX) 4964230557Sjimharris { 4965230557Sjimharris zpt_index = offset + (offset - (offset % 4)) + 4; 4966230557Sjimharris 4967230557Sjimharris *value = scu_controller_scratch_ram_register_read(scic_controller,zpt_index); 4968230557Sjimharris } 4969230557Sjimharris else //offset > SCU_MAX_ZPT_DWORD_INDEX 4970230557Sjimharris { 4971230557Sjimharris offset = offset - 132; 4972230557Sjimharris 4973230557Sjimharris zpt_index = offset + (offset - (offset % 4)) + 4; 4974230557Sjimharris 4975230557Sjimharris *value = scu_controller_scratch_ram_register_read_ext(scic_controller,zpt_index); 4976230557Sjimharris } 4977230557Sjimharris 4978230557Sjimharris return SCI_SUCCESS; 4979230557Sjimharris } 4980230557Sjimharris else 4981230557Sjimharris { 4982230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 4983230557Sjimharris } 4984230557Sjimharris} 4985230557Sjimharris 4986230557Sjimharris// --------------------------------------------------------------------------- 4987230557Sjimharris 4988230557SjimharrisSCI_STATUS scic_controller_write_scratch_ram_dword( 4989230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 4990230557Sjimharris U32 offset, 4991230557Sjimharris U32 value 4992230557Sjimharris) 4993230557Sjimharris{ 4994230557Sjimharris U32 zpt_index; 4995230557Sjimharris 4996230557Sjimharris if (offset < scic_controller_get_scratch_ram_size(controller)) 4997230557Sjimharris { 4998230557Sjimharris SCIC_SDS_CONTROLLER_T * scic_controller = (SCIC_SDS_CONTROLLER_T *)controller; 4999230557Sjimharris 5000230557Sjimharris if(offset <= SCU_MAX_ZPT_DWORD_INDEX) 5001230557Sjimharris { 5002230557Sjimharris zpt_index = offset + (offset - (offset % 4)) + 4; 5003230557Sjimharris 5004230557Sjimharris scu_controller_scratch_ram_register_write(scic_controller,zpt_index,value); 5005230557Sjimharris } 5006230557Sjimharris else //offset > SCU_MAX_ZPT_DWORD_INDEX 5007230557Sjimharris { 5008230557Sjimharris offset = offset - 132; 5009230557Sjimharris 5010230557Sjimharris zpt_index = offset + (offset - (offset % 4)) + 4; 5011230557Sjimharris 5012230557Sjimharris scu_controller_scratch_ram_register_write_ext(scic_controller,zpt_index,value); 5013230557Sjimharris 5014230557Sjimharris } 5015230557Sjimharris 5016230557Sjimharris return SCI_SUCCESS; 5017230557Sjimharris } 5018230557Sjimharris else 5019230557Sjimharris { 5020230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 5021230557Sjimharris } 5022230557Sjimharris} 5023230557Sjimharris 5024230557Sjimharris// --------------------------------------------------------------------------- 5025230557Sjimharris 5026230557SjimharrisSCI_STATUS scic_controller_suspend( 5027230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 5028230557Sjimharris) 5029230557Sjimharris{ 5030230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 5031230557Sjimharris U8 index; 5032230557Sjimharris 5033230557Sjimharris // As a precaution, disable interrupts. The user is required 5034230557Sjimharris // to re-enable interrupts if so desired after the call. 5035230557Sjimharris scic_controller_disable_interrupts(controller); 5036230557Sjimharris 5037230557Sjimharris // Stop all the timers 5038230557Sjimharris // Maybe change the states of the objects to avoid processing stuff. 5039230557Sjimharris 5040230557Sjimharris 5041230557Sjimharris // Suspend the Ports in order to ensure no unexpected 5042230557Sjimharris // frame reception occurs on the links from the target 5043230557Sjimharris for (index = 0; index < SCI_MAX_PORTS; index++) 5044230557Sjimharris scic_sds_port_suspend_port_task_scheduler( 5045230557Sjimharris &(this_controller->port_table[index])); 5046230557Sjimharris 5047230557Sjimharris // Disable/Reset the completion queue and unsolicited frame 5048230557Sjimharris // queue. 5049230557Sjimharris SMU_CQGR_WRITE(this_controller, 0x00000000); 5050230557Sjimharris SCU_UFQGP_WRITE(this_controller, 0x00000000); 5051230557Sjimharris 5052230557Sjimharris // Clear any interrupts that may be pending or may have been generated 5053230557Sjimharris // by setting CQGR and CQPR back to 0 5054230557Sjimharris SMU_ISR_WRITE(this_controller, 0xFFFFFFFF); 5055230557Sjimharris 5056230557Sjimharris //reset the software get pointer to completion queue. 5057230557Sjimharris this_controller->completion_queue_get = 0; 5058230557Sjimharris 5059230557Sjimharris return SCI_SUCCESS; 5060230557Sjimharris} 5061230557Sjimharris 5062230557Sjimharris// --------------------------------------------------------------------------- 5063230557Sjimharris 5064230557SjimharrisSCI_STATUS scic_controller_resume( 5065230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 5066230557Sjimharris) 5067230557Sjimharris{ 5068230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 5069230557Sjimharris U8 index; 5070230557Sjimharris 5071230557Sjimharris // Initialize the completion queue and unsolicited frame queue. 5072230557Sjimharris scic_sds_controller_initialize_completion_queue(this_controller); 5073230557Sjimharris scic_sds_controller_initialize_unsolicited_frame_queue(this_controller); 5074230557Sjimharris 5075230557Sjimharris this_controller->restrict_completions = FALSE; 5076230557Sjimharris 5077230557Sjimharris // Release the port suspensions to allow for further successful 5078230557Sjimharris // operation. 5079230557Sjimharris for (index = 0; index < SCI_MAX_PORTS; index++) 5080230557Sjimharris scic_sds_port_resume_port_task_scheduler( 5081230557Sjimharris &(this_controller->port_table[index])); 5082230557Sjimharris 5083230557Sjimharris //check the link layer status register DWORD sync acquired bit to detect 5084230557Sjimharris //link down event. If there is any link down event happened during controller 5085230557Sjimharris //suspension, restart phy state machine. 5086230557Sjimharris for (index = 0; index < SCI_MAX_PHYS; index ++) 5087230557Sjimharris { 5088230557Sjimharris SCIC_SDS_PHY_T * curr_phy = &this_controller->phy_table[index]; 5089230557Sjimharris U32 link_layer_status = SCU_SAS_LLSTA_READ(curr_phy); 5090230557Sjimharris 5091230557Sjimharris if ((link_layer_status & SCU_SAS_LLSTA_DWORD_SYNCA_BIT) == 0) 5092230557Sjimharris { 5093230557Sjimharris //Need to put the phy back to start OOB. Then an appropriate link event 5094230557Sjimharris //message will be send to scic user. 5095230557Sjimharris scic_sds_phy_restart_starting_state(curr_phy); 5096230557Sjimharris } 5097230557Sjimharris } 5098230557Sjimharris 5099230557Sjimharris return SCI_SUCCESS; 5100230557Sjimharris} 5101230557Sjimharris 5102230557Sjimharris// --------------------------------------------------------------------------- 5103230557Sjimharris 5104230557SjimharrisSCI_STATUS scic_controller_transition( 5105230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 5106230557Sjimharris BOOL restrict_completions 5107230557Sjimharris) 5108230557Sjimharris{ 5109230557Sjimharris SCI_STATUS result = SCI_FAILURE_INVALID_STATE; 5110230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 5111230557Sjimharris U8 index; 5112230557Sjimharris 5113230557Sjimharris SCIC_LOG_TRACE(( 5114230557Sjimharris sci_base_object_get_logger(controller), 5115230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 5116230557Sjimharris "scic_controller_transition(0x%x) enter\n", 5117230557Sjimharris controller 5118230557Sjimharris )); 5119230557Sjimharris 5120230557Sjimharris if (this_controller->parent.state_machine.current_state_id 5121230557Sjimharris == SCI_BASE_CONTROLLER_STATE_READY) 5122230557Sjimharris { 5123230557Sjimharris // Ensure that there are no outstanding IO operations at this 5124230557Sjimharris // time. 5125230557Sjimharris for (index = 0; index < SCI_MAX_PORTS; index++) 5126230557Sjimharris { 5127230557Sjimharris if (this_controller->port_table[index].started_request_count != 0) 5128230557Sjimharris return result; 5129230557Sjimharris } 5130230557Sjimharris 5131230557Sjimharris scic_controller_suspend(controller); 5132230557Sjimharris 5133230557Sjimharris // Loop through the memory descriptor list and reprogram 5134230557Sjimharris // the silicon memory registers accordingly. 5135230557Sjimharris result = scic_sds_controller_validate_memory_descriptor_table( 5136230557Sjimharris this_controller); 5137230557Sjimharris if (result == SCI_SUCCESS) 5138230557Sjimharris { 5139230557Sjimharris scic_sds_controller_ram_initialization(this_controller); 5140230557Sjimharris this_controller->restrict_completions = restrict_completions; 5141230557Sjimharris } 5142230557Sjimharris 5143230557Sjimharris scic_controller_resume(controller); 5144230557Sjimharris } 5145230557Sjimharris 5146230557Sjimharris return result; 5147230557Sjimharris} 5148230557Sjimharris 5149230557Sjimharris// --------------------------------------------------------------------------- 5150230557Sjimharris 5151230557SjimharrisSCI_STATUS scic_controller_get_max_ports( 5152230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 5153230557Sjimharris U8 * count 5154230557Sjimharris) 5155230557Sjimharris{ 5156230557Sjimharris *count = SCI_MAX_PORTS; 5157230557Sjimharris return SCI_SUCCESS; 5158230557Sjimharris} 5159230557Sjimharris 5160230557Sjimharris// --------------------------------------------------------------------------- 5161230557Sjimharris 5162230557SjimharrisSCI_STATUS scic_controller_get_max_phys( 5163230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 5164230557Sjimharris U8 * count 5165230557Sjimharris) 5166230557Sjimharris{ 5167230557Sjimharris *count = SCI_MAX_PHYS; 5168230557Sjimharris return SCI_SUCCESS; 5169230557Sjimharris} 5170230557Sjimharris 5171230557Sjimharris 5172230557Sjimharris//****************************************************************************** 5173230557Sjimharris//* CONTROLLER STATE MACHINE 5174230557Sjimharris//****************************************************************************** 5175230557Sjimharris 5176230557Sjimharris/** 5177230557Sjimharris * This macro returns the maximum number of logical ports supported by the 5178230557Sjimharris * hardware. The caller passes in the value read from the device context 5179230557Sjimharris * capacity register and this macro will mash and shift the value 5180230557Sjimharris * appropriately. 5181230557Sjimharris */ 5182230557Sjimharris#define smu_dcc_get_max_ports(dcc_value) \ 5183230557Sjimharris ( \ 5184230557Sjimharris ( ((U32)((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_MASK)) \ 5185230557Sjimharris >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT ) + 1\ 5186230557Sjimharris ) 5187230557Sjimharris 5188230557Sjimharris/** 5189230557Sjimharris * This macro returns the maximum number of task contexts supported by the 5190230557Sjimharris * hardware. The caller passes in the value read from the device context 5191230557Sjimharris * capacity register and this macro will mash and shift the value 5192230557Sjimharris * appropriately. 5193230557Sjimharris */ 5194230557Sjimharris#define smu_dcc_get_max_task_context(dcc_value) \ 5195230557Sjimharris ( \ 5196230557Sjimharris ( ((U32)((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_MASK)) \ 5197230557Sjimharris >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_SHIFT ) + 1\ 5198230557Sjimharris ) 5199230557Sjimharris 5200230557Sjimharris/** 5201230557Sjimharris * This macro returns the maximum number of remote node contexts supported 5202230557Sjimharris * by the hardware. The caller passes in the value read from the device 5203230557Sjimharris * context capacity register and this macro will mash and shift the value 5204230557Sjimharris * appropriately. 5205230557Sjimharris */ 5206230557Sjimharris#define smu_dcc_get_max_remote_node_context(dcc_value) \ 5207230557Sjimharris ( \ 5208230557Sjimharris ( ( (U32)((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_MASK) )\ 5209230557Sjimharris >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_SHIFT ) + 1\ 5210230557Sjimharris ) 5211230557Sjimharris 5212230557Sjimharris//***************************************************************************** 5213230557Sjimharris//* DEFAULT STATE HANDLERS 5214230557Sjimharris//***************************************************************************** 5215230557Sjimharris 5216230557Sjimharris/** 5217230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER default start 5218230557Sjimharris * io/task handler is in place. 5219230557Sjimharris * - Issue a warning message 5220230557Sjimharris * 5221230557Sjimharris * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast 5222230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 5223230557Sjimharris * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which, if it was 5224230557Sjimharris * used, would be cast to a SCIC_SDS_REMOTE_DEVICE. 5225230557Sjimharris * @param[in] io_request This is the SCI_BASE_REQUEST which, if it was used, 5226230557Sjimharris * would be cast to a SCIC_SDS_IO_REQUEST. 5227230557Sjimharris * @param[in] io_tag This is the IO tag to be assigned to the IO request or 5228230557Sjimharris * SCI_CONTROLLER_INVALID_IO_TAG. 5229230557Sjimharris * 5230230557Sjimharris * @return SCI_STATUS 5231230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 5232230557Sjimharris */ 5233230557Sjimharrisstatic 5234230557SjimharrisSCI_STATUS scic_sds_controller_default_start_operation_handler( 5235230557Sjimharris SCI_BASE_CONTROLLER_T *controller, 5236230557Sjimharris SCI_BASE_REMOTE_DEVICE_T *remote_device, 5237230557Sjimharris SCI_BASE_REQUEST_T *io_request, 5238230557Sjimharris U16 io_tag 5239230557Sjimharris) 5240230557Sjimharris{ 5241230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 5242230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 5243230557Sjimharris 5244230557Sjimharris SCIC_LOG_WARNING(( 5245230557Sjimharris sci_base_object_get_logger(this_controller), 5246230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 5247230557Sjimharris "SCIC Controller requested to start an io/task from invalid state %d\n", 5248230557Sjimharris sci_base_state_machine_get_state( 5249230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller)) 5250230557Sjimharris )); 5251230557Sjimharris 5252230557Sjimharris return SCI_FAILURE_INVALID_STATE; 5253230557Sjimharris} 5254230557Sjimharris 5255230557Sjimharris/** 5256230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER default 5257230557Sjimharris * request handler is in place. 5258230557Sjimharris * - Issue a warning message 5259230557Sjimharris * 5260230557Sjimharris * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast 5261230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 5262230557Sjimharris * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which, if it was 5263230557Sjimharris * used, would be cast to a SCIC_SDS_REMOTE_DEVICE. 5264230557Sjimharris * @param[in] io_request This is the SCI_BASE_REQUEST which, if it was used, 5265230557Sjimharris * would be cast to a SCIC_SDS_IO_REQUEST. 5266230557Sjimharris * 5267230557Sjimharris * @return SCI_STATUS 5268230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 5269230557Sjimharris */ 5270230557Sjimharrisstatic 5271230557SjimharrisSCI_STATUS scic_sds_controller_default_request_handler( 5272230557Sjimharris SCI_BASE_CONTROLLER_T *controller, 5273230557Sjimharris SCI_BASE_REMOTE_DEVICE_T *remote_device, 5274230557Sjimharris SCI_BASE_REQUEST_T *io_request 5275230557Sjimharris) 5276230557Sjimharris{ 5277230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 5278230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 5279230557Sjimharris 5280230557Sjimharris SCIC_LOG_WARNING(( 5281230557Sjimharris sci_base_object_get_logger(this_controller), 5282230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 5283230557Sjimharris "SCIC Controller request operation from invalid state %d\n", 5284230557Sjimharris sci_base_state_machine_get_state( 5285230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller)) 5286230557Sjimharris )); 5287230557Sjimharris 5288230557Sjimharris return SCI_FAILURE_INVALID_STATE; 5289230557Sjimharris} 5290230557Sjimharris 5291230557Sjimharris//***************************************************************************** 5292230557Sjimharris//* GENERAL (COMMON) STATE HANDLERS 5293230557Sjimharris//***************************************************************************** 5294230557Sjimharris 5295230557Sjimharris/** 5296230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the ready state 5297230557Sjimharris * reset handler is in place. 5298230557Sjimharris * - Transition to SCI_BASE_CONTROLLER_STATE_RESETTING 5299230557Sjimharris * 5300230557Sjimharris * @param[in] controller The SCI_BASE_CONTROLLER object which is cast into a 5301230557Sjimharris * SCIC_SDS_CONTROLLER object. 5302230557Sjimharris * 5303230557Sjimharris * @return SCI_STATUS 5304230557Sjimharris * @retval SCI_SUCCESS 5305230557Sjimharris */ 5306230557Sjimharrisstatic 5307230557SjimharrisSCI_STATUS scic_sds_controller_general_reset_handler( 5308230557Sjimharris SCI_BASE_CONTROLLER_T *controller 5309230557Sjimharris) 5310230557Sjimharris{ 5311230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 5312230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 5313230557Sjimharris 5314230557Sjimharris SCIC_LOG_TRACE(( 5315230557Sjimharris sci_base_object_get_logger(controller), 5316230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 5317230557Sjimharris "scic_sds_controller_resetting_state_enter(0x%x) enter\n", 5318230557Sjimharris controller 5319230557Sjimharris )); 5320230557Sjimharris 5321230557Sjimharris //Release resource. So far only resource to be released are timers. 5322230557Sjimharris scic_sds_controller_release_resource(this_controller); 5323230557Sjimharris 5324230557Sjimharris // The reset operation is not a graceful cleanup just perform the state 5325230557Sjimharris // transition. 5326230557Sjimharris sci_base_state_machine_change_state( 5327230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 5328230557Sjimharris SCI_BASE_CONTROLLER_STATE_RESETTING 5329230557Sjimharris ); 5330230557Sjimharris 5331230557Sjimharris return SCI_SUCCESS; 5332230557Sjimharris} 5333230557Sjimharris 5334230557Sjimharris//***************************************************************************** 5335230557Sjimharris//* RESET STATE HANDLERS 5336230557Sjimharris//***************************************************************************** 5337230557Sjimharris 5338230557Sjimharris/** 5339230557Sjimharris * This method is the SCIC_SDS_CONTROLLER initialize handler for the reset 5340230557Sjimharris * state. 5341230557Sjimharris * - Currently this function does nothing 5342230557Sjimharris * 5343230557Sjimharris * @param[in] controller This is the SCI_BASE_CONTROLLER object which is cast 5344230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 5345230557Sjimharris * 5346230557Sjimharris * @return SCI_STATUS 5347230557Sjimharris * @retval SCI_FAILURE 5348230557Sjimharris * 5349230557Sjimharris * @todo This function is not yet implemented and is a valid request from the 5350230557Sjimharris * reset state. 5351230557Sjimharris */ 5352230557Sjimharrisstatic 5353230557SjimharrisSCI_STATUS scic_sds_controller_reset_state_initialize_handler( 5354230557Sjimharris SCI_BASE_CONTROLLER_T *controller 5355230557Sjimharris) 5356230557Sjimharris{ 5357230557Sjimharris U32 index; 5358230557Sjimharris SCI_STATUS result = SCI_SUCCESS; 5359230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 5360230557Sjimharris 5361230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 5362230557Sjimharris 5363230557Sjimharris SCIC_LOG_TRACE(( 5364230557Sjimharris sci_base_object_get_logger(controller), 5365230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_INITIALIZATION, 5366230557Sjimharris "scic_sds_controller_reset_state_initialize_handler(0x%x) enter\n", 5367230557Sjimharris controller 5368230557Sjimharris )); 5369230557Sjimharris 5370230557Sjimharris sci_base_state_machine_change_state( 5371230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 5372230557Sjimharris SCI_BASE_CONTROLLER_STATE_INITIALIZING 5373230557Sjimharris ); 5374230557Sjimharris 5375230557Sjimharris this_controller->timeout_timer = scic_cb_timer_create( 5376230557Sjimharris controller, 5377230557Sjimharris scic_sds_controller_timeout_handler, 5378230557Sjimharris controller 5379230557Sjimharris ); 5380230557Sjimharris 5381230557Sjimharris scic_sds_controller_initialize_power_control(this_controller); 5382230557Sjimharris 5383230557Sjimharris /// todo: This should really be done in the reset state enter but 5384230557Sjimharris /// the controller has not yet been initialized before getting 5385230557Sjimharris /// to the reset enter state so the PCI BAR is not yet assigned 5386230557Sjimharris scic_sds_controller_reset_hardware(this_controller); 5387230557Sjimharris 5388230557Sjimharris#if defined(ARLINGTON_BUILD) 5389230557Sjimharris scic_sds_controller_lex_atux_initialization(this_controller); 5390230557Sjimharris#elif defined(PLEASANT_RIDGE_BUILD) \ 5391230557Sjimharris || defined(PBG_HBA_A0_BUILD) \ 5392230557Sjimharris || defined(PBG_HBA_A2_BUILD) 5393230557Sjimharris scic_sds_controller_afe_initialization(this_controller); 5394230557Sjimharris#elif defined(PBG_HBA_BETA_BUILD) || defined(PBG_BUILD) 5395230557Sjimharris // There is nothing to do here for B0 since we do not have to 5396230557Sjimharris // program the AFE registers. 5397230557Sjimharris /// @todo The AFE settings are supposed to be correct for the B0 but 5398230557Sjimharris /// presently they seem to be wrong. 5399230557Sjimharris scic_sds_controller_afe_initialization(this_controller); 5400230557Sjimharris#else // !defined(ARLINGTON_BUILD) && !defined(PLEASANT_RIDGE_BUILD) 5401230557Sjimharris // What other systems do we want to add here? 5402230557Sjimharris#endif // !defined(ARLINGTON_BUILD) && !defined(PLEASANT_RIDGE_BUILD) 5403230557Sjimharris 5404230557Sjimharris if (SCI_SUCCESS == result) 5405230557Sjimharris { 5406230557Sjimharris U32 status; 5407230557Sjimharris U32 terminate_loop; 5408230557Sjimharris 5409230557Sjimharris // Take the hardware out of reset 5410230557Sjimharris SMU_SMUSRCR_WRITE(this_controller, 0x00000000); 5411230557Sjimharris 5412230557Sjimharris /// @todo Provide meaningfull error code for hardware failure 5413230557Sjimharris //result = SCI_FAILURE_CONTROLLER_HARDWARE; 5414230557Sjimharris result = SCI_FAILURE; 5415230557Sjimharris terminate_loop = 100; 5416230557Sjimharris 5417230557Sjimharris while (terminate_loop-- && (result != SCI_SUCCESS)) 5418230557Sjimharris { 5419230557Sjimharris // Loop until the hardware reports success 5420230557Sjimharris scic_cb_stall_execution(SCU_CONTEXT_RAM_INIT_STALL_TIME); 5421230557Sjimharris status = SMU_SMUCSR_READ(this_controller); 5422230557Sjimharris 5423230557Sjimharris if ((status & SCU_RAM_INIT_COMPLETED) == SCU_RAM_INIT_COMPLETED) 5424230557Sjimharris { 5425230557Sjimharris result = SCI_SUCCESS; 5426230557Sjimharris } 5427230557Sjimharris } 5428230557Sjimharris } 5429230557Sjimharris 5430230557Sjimharris#ifdef ARLINGTON_BUILD 5431230557Sjimharris scic_sds_controller_enable_chipwatch(this_controller); 5432230557Sjimharris#endif 5433230557Sjimharris 5434230557Sjimharris if (result == SCI_SUCCESS) 5435230557Sjimharris { 5436230557Sjimharris U32 max_supported_ports; 5437230557Sjimharris U32 max_supported_devices; 5438230557Sjimharris U32 max_supported_io_requests; 5439230557Sjimharris U32 device_context_capacity; 5440230557Sjimharris 5441230557Sjimharris // Determine what are the actaul device capacities that the 5442230557Sjimharris // hardware will support 5443230557Sjimharris device_context_capacity = SMU_DCC_READ(this_controller); 5444230557Sjimharris 5445230557Sjimharris max_supported_ports = 5446230557Sjimharris smu_dcc_get_max_ports(device_context_capacity); 5447230557Sjimharris max_supported_devices = 5448230557Sjimharris smu_dcc_get_max_remote_node_context(device_context_capacity); 5449230557Sjimharris max_supported_io_requests = 5450230557Sjimharris smu_dcc_get_max_task_context(device_context_capacity); 5451230557Sjimharris 5452230557Sjimharris // Make all PEs that are unassigned match up with the logical ports 5453230557Sjimharris for (index = 0; index < max_supported_ports; index++) 5454230557Sjimharris { 5455230557Sjimharris scu_register_write( 5456230557Sjimharris this_controller, 5457230557Sjimharris this_controller->scu_registers->peg0.ptsg.protocol_engine[index], 5458230557Sjimharris index 5459230557Sjimharris ); 5460230557Sjimharris } 5461230557Sjimharris 5462230557Sjimharris // Now that we have the correct hardware reported minimum values 5463230557Sjimharris // build the MDL for the controller. Default to a performance 5464230557Sjimharris // configuration. 5465230557Sjimharris scic_controller_set_mode(this_controller, SCI_MODE_SPEED); 5466230557Sjimharris 5467230557Sjimharris // Record the smaller of the two capacity values 5468230557Sjimharris this_controller->logical_port_entries = 5469230557Sjimharris MIN(max_supported_ports, this_controller->logical_port_entries); 5470230557Sjimharris 5471230557Sjimharris this_controller->task_context_entries = 5472230557Sjimharris MIN(max_supported_io_requests, this_controller->task_context_entries); 5473230557Sjimharris 5474230557Sjimharris this_controller->remote_node_entries = 5475230557Sjimharris MIN(max_supported_devices, this_controller->remote_node_entries); 5476230557Sjimharris } 5477230557Sjimharris 5478230557Sjimharris // Initialize hardware PCI Relaxed ordering in DMA engines 5479230557Sjimharris if (result == SCI_SUCCESS) 5480230557Sjimharris { 5481230557Sjimharris U32 dma_configuration; 5482230557Sjimharris 5483230557Sjimharris // Configure the payload DMA 5484230557Sjimharris dma_configuration = SCU_PDMACR_READ(this_controller); 5485230557Sjimharris dma_configuration |= SCU_PDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE); 5486230557Sjimharris SCU_PDMACR_WRITE(this_controller, dma_configuration); 5487230557Sjimharris 5488230557Sjimharris // Configure the control DMA 5489230557Sjimharris dma_configuration = SCU_CDMACR_READ(this_controller); 5490230557Sjimharris dma_configuration |= SCU_CDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE); 5491230557Sjimharris SCU_CDMACR_WRITE(this_controller, dma_configuration); 5492230557Sjimharris } 5493230557Sjimharris 5494230557Sjimharris // Initialize the PHYs before the PORTs because the PHY registers 5495230557Sjimharris // are accessed during the port initialization. 5496230557Sjimharris if (result == SCI_SUCCESS) 5497230557Sjimharris { 5498230557Sjimharris // Initialize the phys 5499230557Sjimharris for (index = 0; 5500230557Sjimharris (result == SCI_SUCCESS) && (index < SCI_MAX_PHYS); 5501230557Sjimharris index++) 5502230557Sjimharris { 5503230557Sjimharris result = scic_sds_phy_initialize( 5504230557Sjimharris &this_controller->phy_table[index], 5505230557Sjimharris &this_controller->scu_registers->peg0.pe[index].tl, 5506230557Sjimharris &this_controller->scu_registers->peg0.pe[index].ll 5507230557Sjimharris ); 5508230557Sjimharris } 5509230557Sjimharris } 5510230557Sjimharris 5511230557Sjimharris //Initialize the SGPIO Unit for HARDWARE controlled SGPIO 5512230557Sjimharris if(result == SCI_SUCCESS) 5513230557Sjimharris { 5514230557Sjimharris scic_sgpio_hardware_initialize(this_controller); 5515230557Sjimharris } 5516230557Sjimharris 5517230557Sjimharris if (result == SCI_SUCCESS) 5518230557Sjimharris { 5519230557Sjimharris // Initialize the logical ports 5520230557Sjimharris for (index = 0; 5521230557Sjimharris (index < this_controller->logical_port_entries) 5522230557Sjimharris && (result == SCI_SUCCESS); 5523230557Sjimharris index++) 5524230557Sjimharris { 5525230557Sjimharris result = scic_sds_port_initialize( 5526230557Sjimharris &this_controller->port_table[index], 5527230557Sjimharris &this_controller->scu_registers->peg0.ptsg.port[index], 5528230557Sjimharris &this_controller->scu_registers->peg0.ptsg.protocol_engine, 5529230557Sjimharris &this_controller->scu_registers->peg0.viit[index] 5530230557Sjimharris ); 5531230557Sjimharris } 5532230557Sjimharris } 5533230557Sjimharris 5534230557Sjimharris if (SCI_SUCCESS == result) 5535230557Sjimharris { 5536230557Sjimharris result = scic_sds_port_configuration_agent_initialize( 5537230557Sjimharris this_controller, 5538230557Sjimharris &this_controller->port_agent 5539230557Sjimharris ); 5540230557Sjimharris } 5541230557Sjimharris 5542230557Sjimharris // Advance the controller state machine 5543230557Sjimharris if (result == SCI_SUCCESS) 5544230557Sjimharris { 5545230557Sjimharris sci_base_state_machine_change_state( 5546230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 5547230557Sjimharris SCI_BASE_CONTROLLER_STATE_INITIALIZED 5548230557Sjimharris ); 5549230557Sjimharris } 5550230557Sjimharris else 5551230557Sjimharris { 5552230557Sjimharris //stay in the same state and release the resource 5553230557Sjimharris scic_sds_controller_release_resource(this_controller); 5554230557Sjimharris 5555230557Sjimharris SCIC_LOG_TRACE(( 5556230557Sjimharris sci_base_object_get_logger(controller), 5557230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_INITIALIZATION, 5558230557Sjimharris "Invalid Port Configuration from scic_sds_controller_reset_state_initialize_handler(0x%x) \n", 5559230557Sjimharris controller 5560230557Sjimharris )); 5561230557Sjimharris 5562230557Sjimharris } 5563230557Sjimharris 5564230557Sjimharris return result; 5565230557Sjimharris} 5566230557Sjimharris 5567230557Sjimharris//***************************************************************************** 5568230557Sjimharris//* INITIALIZED STATE HANDLERS 5569230557Sjimharris//***************************************************************************** 5570230557Sjimharris 5571230557Sjimharris/** 5572230557Sjimharris * This method is the SCIC_SDS_CONTROLLER start handler for the initialized 5573230557Sjimharris * state. 5574230557Sjimharris * - Validate we have a good memory descriptor table 5575230557Sjimharris * - Initialze the physical memory before programming the hardware 5576230557Sjimharris * - Program the SCU hardware with the physical memory addresses passed in 5577230557Sjimharris * the memory descriptor table. 5578230557Sjimharris * - Initialzie the TCi pool 5579230557Sjimharris * - Initialize the RNi pool 5580230557Sjimharris * - Initialize the completion queue 5581230557Sjimharris * - Initialize the unsolicited frame data 5582230557Sjimharris * - Take the SCU port task scheduler out of reset 5583230557Sjimharris * - Start the first phy object. 5584230557Sjimharris * - Transition to SCI_BASE_CONTROLLER_STATE_STARTING. 5585230557Sjimharris * 5586230557Sjimharris * @param[in] controller This is the SCI_BASE_CONTROLLER object which is cast 5587230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 5588230557Sjimharris * @param[in] timeout This is the allowed time for the controller object to 5589230557Sjimharris * reach the started state. 5590230557Sjimharris * 5591230557Sjimharris * @return SCI_STATUS 5592230557Sjimharris * @retval SCI_SUCCESS if all of the controller start operations complete 5593230557Sjimharris * @retval SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD if one or more of the 5594230557Sjimharris * memory descriptor fields is invalid. 5595230557Sjimharris */ 5596230557Sjimharrisstatic 5597230557SjimharrisSCI_STATUS scic_sds_controller_initialized_state_start_handler( 5598230557Sjimharris SCI_BASE_CONTROLLER_T * controller, 5599230557Sjimharris U32 timeout 5600230557Sjimharris) 5601230557Sjimharris{ 5602230557Sjimharris U16 index; 5603230557Sjimharris SCI_STATUS result; 5604230557Sjimharris SCIC_SDS_CONTROLLER_T * this_controller; 5605230557Sjimharris 5606230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 5607230557Sjimharris 5608230557Sjimharris // Make sure that the SCI User filled in the memory descriptor table correctly 5609230557Sjimharris result = scic_sds_controller_validate_memory_descriptor_table(this_controller); 5610230557Sjimharris 5611230557Sjimharris if (result == SCI_SUCCESS) 5612230557Sjimharris { 5613230557Sjimharris // The memory descriptor list looks good so program the hardware 5614230557Sjimharris scic_sds_controller_ram_initialization(this_controller); 5615230557Sjimharris } 5616230557Sjimharris 5617230557Sjimharris if (SCI_SUCCESS == result) 5618230557Sjimharris { 5619230557Sjimharris // Build the TCi free pool 5620230557Sjimharris sci_pool_initialize(this_controller->tci_pool); 5621230557Sjimharris for (index = 0; index < this_controller->task_context_entries; index++) 5622230557Sjimharris { 5623230557Sjimharris sci_pool_put(this_controller->tci_pool, index); 5624230557Sjimharris } 5625230557Sjimharris 5626230557Sjimharris // Build the RNi free pool 5627230557Sjimharris scic_sds_remote_node_table_initialize( 5628230557Sjimharris &this_controller->available_remote_nodes, 5629230557Sjimharris this_controller->remote_node_entries 5630230557Sjimharris ); 5631230557Sjimharris } 5632230557Sjimharris 5633230557Sjimharris if (SCI_SUCCESS == result) 5634230557Sjimharris { 5635230557Sjimharris // Before anything else lets make sure we will not be interrupted 5636230557Sjimharris // by the hardware. 5637230557Sjimharris scic_controller_disable_interrupts(controller); 5638230557Sjimharris 5639230557Sjimharris // Enable the port task scheduler 5640230557Sjimharris scic_sds_controller_enable_port_task_scheduler(this_controller); 5641230557Sjimharris 5642230557Sjimharris // Assign all the task entries to this controller physical function 5643230557Sjimharris scic_sds_controller_assign_task_entries(this_controller); 5644230557Sjimharris 5645230557Sjimharris // Now initialze the completion queue 5646230557Sjimharris scic_sds_controller_initialize_completion_queue(this_controller); 5647230557Sjimharris 5648230557Sjimharris // Initialize the unsolicited frame queue for use 5649230557Sjimharris scic_sds_controller_initialize_unsolicited_frame_queue(this_controller); 5650230557Sjimharris 5651230557Sjimharris // Setup the phy start timer 5652230557Sjimharris result = scic_sds_controller_initialize_phy_startup(this_controller); 5653230557Sjimharris } 5654230557Sjimharris 5655230557Sjimharris // Start all of the ports on this controller 5656230557Sjimharris for ( 5657230557Sjimharris index = 0; 5658230557Sjimharris (index < this_controller->logical_port_entries) && (result == SCI_SUCCESS); 5659230557Sjimharris index++ 5660230557Sjimharris ) 5661230557Sjimharris { 5662230557Sjimharris result = this_controller->port_table[index]. 5663230557Sjimharris state_handlers->parent.start_handler(&this_controller->port_table[index].parent); 5664230557Sjimharris } 5665230557Sjimharris 5666230557Sjimharris if (SCI_SUCCESS == result) 5667230557Sjimharris { 5668230557Sjimharris scic_sds_controller_start_next_phy(this_controller); 5669230557Sjimharris 5670230557Sjimharris // See if the user requested to timeout this operation. 5671230557Sjimharris if (timeout != 0) 5672230557Sjimharris scic_cb_timer_start(controller, this_controller->timeout_timer, timeout); 5673230557Sjimharris 5674230557Sjimharris sci_base_state_machine_change_state( 5675230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 5676230557Sjimharris SCI_BASE_CONTROLLER_STATE_STARTING 5677230557Sjimharris ); 5678230557Sjimharris } 5679230557Sjimharris 5680230557Sjimharris return result; 5681230557Sjimharris} 5682230557Sjimharris 5683230557Sjimharris//***************************************************************************** 5684230557Sjimharris//* STARTING STATE HANDLERS 5685230557Sjimharris//***************************************************************************** 5686230557Sjimharris 5687230557Sjimharris/** 5688230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the starting state 5689230557Sjimharris * link up handler is called. This method will perform the following: 5690230557Sjimharris * - Stop the phy timer 5691230557Sjimharris * - Start the next phy 5692230557Sjimharris * - Report the link up condition to the port object 5693230557Sjimharris * 5694230557Sjimharris * @param[in] controller This is SCIC_SDS_CONTROLLER which receives the link up 5695230557Sjimharris * notification. 5696230557Sjimharris * @param[in] port This is SCIC_SDS_PORT with which the phy is associated. 5697230557Sjimharris * @param[in] phy This is the SCIC_SDS_PHY which has gone link up. 5698230557Sjimharris * 5699230557Sjimharris * @return none 5700230557Sjimharris */ 5701230557Sjimharrisstatic 5702230557Sjimharrisvoid scic_sds_controller_starting_state_link_up_handler( 5703230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 5704230557Sjimharris SCIC_SDS_PORT_T *port, 5705230557Sjimharris SCIC_SDS_PHY_T *phy 5706230557Sjimharris) 5707230557Sjimharris{ 5708230557Sjimharris scic_sds_controller_phy_timer_stop(this_controller); 5709230557Sjimharris 5710230557Sjimharris this_controller->port_agent.link_up_handler( 5711230557Sjimharris this_controller, &this_controller->port_agent, port, phy 5712230557Sjimharris ); 5713230557Sjimharris //scic_sds_port_link_up(port, phy); 5714230557Sjimharris 5715230557Sjimharris scic_sds_controller_start_next_phy(this_controller); 5716230557Sjimharris} 5717230557Sjimharris 5718230557Sjimharris/** 5719230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the starting state 5720230557Sjimharris * link down handler is called. 5721230557Sjimharris * - Report the link down condition to the port object 5722230557Sjimharris * 5723230557Sjimharris * @param[in] controller This is SCIC_SDS_CONTROLLER which receives the 5724230557Sjimharris * link down notification. 5725230557Sjimharris * @param[in] port This is SCIC_SDS_PORT with which the phy is associated. 5726230557Sjimharris * @param[in] phy This is the SCIC_SDS_PHY which has gone link down. 5727230557Sjimharris * 5728230557Sjimharris * @return none 5729230557Sjimharris */ 5730230557Sjimharrisstatic 5731230557Sjimharrisvoid scic_sds_controller_starting_state_link_down_handler( 5732230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 5733230557Sjimharris SCIC_SDS_PORT_T *port, 5734230557Sjimharris SCIC_SDS_PHY_T *phy 5735230557Sjimharris) 5736230557Sjimharris{ 5737230557Sjimharris this_controller->port_agent.link_down_handler( 5738230557Sjimharris this_controller, &this_controller->port_agent, port, phy 5739230557Sjimharris ); 5740230557Sjimharris //scic_sds_port_link_down(port, phy); 5741230557Sjimharris} 5742230557Sjimharris 5743230557Sjimharris//***************************************************************************** 5744230557Sjimharris//* READY STATE HANDLERS 5745230557Sjimharris//***************************************************************************** 5746230557Sjimharris 5747230557Sjimharris/** 5748230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the ready state 5749230557Sjimharris * stop handler is called. 5750230557Sjimharris * - Start the timeout timer 5751230557Sjimharris * - Transition to SCI_BASE_CONTROLLER_STATE_STOPPING. 5752230557Sjimharris * 5753230557Sjimharris * @param[in] controller The SCI_BASE_CONTROLLER object which is cast into a 5754230557Sjimharris * SCIC_SDS_CONTROLLER object. 5755230557Sjimharris * @param[in] timeout The timeout for when the stop operation should report a 5756230557Sjimharris * failure. 5757230557Sjimharris * 5758230557Sjimharris * @return SCI_STATUS 5759230557Sjimharris * @retval SCI_SUCCESS 5760230557Sjimharris */ 5761230557Sjimharrisstatic 5762230557SjimharrisSCI_STATUS scic_sds_controller_ready_state_stop_handler( 5763230557Sjimharris SCI_BASE_CONTROLLER_T *controller, 5764230557Sjimharris U32 timeout 5765230557Sjimharris) 5766230557Sjimharris{ 5767230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 5768230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 5769230557Sjimharris 5770230557Sjimharris // See if the user requested to timeout this operation 5771230557Sjimharris if (timeout != 0) 5772230557Sjimharris scic_cb_timer_start(controller, this_controller->timeout_timer, timeout); 5773230557Sjimharris 5774230557Sjimharris sci_base_state_machine_change_state( 5775230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 5776230557Sjimharris SCI_BASE_CONTROLLER_STATE_STOPPING 5777230557Sjimharris ); 5778230557Sjimharris 5779230557Sjimharris return SCI_SUCCESS; 5780230557Sjimharris} 5781230557Sjimharris 5782230557Sjimharris/** 5783230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the ready state 5784230557Sjimharris * and the start io handler is called. 5785230557Sjimharris * - Start the io request on the remote device 5786230557Sjimharris * - if successful 5787230557Sjimharris * - assign the io_request to the io_request_table 5788230557Sjimharris * - post the request to the hardware 5789230557Sjimharris * 5790230557Sjimharris * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast 5791230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 5792230557Sjimharris * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a 5793230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 5794230557Sjimharris * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a 5795230557Sjimharris * SCIC_SDS_IO_REQUEST object. 5796230557Sjimharris * @param[in] io_tag This is the IO tag to be assigned to the IO request or 5797230557Sjimharris * SCI_CONTROLLER_INVALID_IO_TAG. 5798230557Sjimharris * 5799230557Sjimharris * @return SCI_STATUS 5800230557Sjimharris * @retval SCI_SUCCESS if the start io operation succeeds 5801230557Sjimharris * @retval SCI_FAILURE_INSUFFICIENT_RESOURCES if the IO tag could not be 5802230557Sjimharris * allocated for the io request. 5803230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid 5804230557Sjimharris * state to accept io requests. 5805230557Sjimharris * 5806230557Sjimharris * @todo How does the io_tag parameter get assigned to the io request? 5807230557Sjimharris */ 5808230557Sjimharrisstatic 5809230557SjimharrisSCI_STATUS scic_sds_controller_ready_state_start_io_handler( 5810230557Sjimharris SCI_BASE_CONTROLLER_T *controller, 5811230557Sjimharris SCI_BASE_REMOTE_DEVICE_T *remote_device, 5812230557Sjimharris SCI_BASE_REQUEST_T *io_request, 5813230557Sjimharris U16 io_tag 5814230557Sjimharris) 5815230557Sjimharris{ 5816230557Sjimharris SCI_STATUS status; 5817230557Sjimharris 5818230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 5819230557Sjimharris SCIC_SDS_REQUEST_T *the_request; 5820230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T *the_device; 5821230557Sjimharris 5822230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 5823230557Sjimharris the_request = (SCIC_SDS_REQUEST_T *)io_request; 5824230557Sjimharris the_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 5825230557Sjimharris 5826230557Sjimharris status = scic_sds_remote_device_start_io(this_controller, the_device, the_request); 5827230557Sjimharris 5828230557Sjimharris if (status == SCI_SUCCESS) 5829230557Sjimharris { 5830230557Sjimharris this_controller->io_request_table[ 5831230557Sjimharris scic_sds_io_tag_get_index(the_request->io_tag)] = the_request; 5832230557Sjimharris 5833230557Sjimharris scic_sds_controller_post_request( 5834230557Sjimharris this_controller, 5835230557Sjimharris scic_sds_request_get_post_context(the_request) 5836230557Sjimharris ); 5837230557Sjimharris } 5838230557Sjimharris 5839230557Sjimharris return status; 5840230557Sjimharris} 5841230557Sjimharris 5842230557Sjimharris/** 5843230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the ready state 5844230557Sjimharris * and the complete io handler is called. 5845230557Sjimharris * - Complete the io request on the remote device 5846230557Sjimharris * - if successful 5847230557Sjimharris * - remove the io_request to the io_request_table 5848230557Sjimharris * 5849230557Sjimharris * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast 5850230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 5851230557Sjimharris * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a 5852230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 5853230557Sjimharris * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a 5854230557Sjimharris * SCIC_SDS_IO_REQUEST object. 5855230557Sjimharris * 5856230557Sjimharris * @return SCI_STATUS 5857230557Sjimharris * @retval SCI_SUCCESS if the start io operation succeeds 5858230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid 5859230557Sjimharris * state to accept io requests. 5860230557Sjimharris */ 5861230557Sjimharrisstatic 5862230557SjimharrisSCI_STATUS scic_sds_controller_ready_state_complete_io_handler( 5863230557Sjimharris SCI_BASE_CONTROLLER_T *controller, 5864230557Sjimharris SCI_BASE_REMOTE_DEVICE_T *remote_device, 5865230557Sjimharris SCI_BASE_REQUEST_T *io_request 5866230557Sjimharris) 5867230557Sjimharris{ 5868230557Sjimharris U16 index; 5869230557Sjimharris SCI_STATUS status; 5870230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 5871230557Sjimharris SCIC_SDS_REQUEST_T *the_request; 5872230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T *the_device; 5873230557Sjimharris 5874230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 5875230557Sjimharris the_request = (SCIC_SDS_REQUEST_T *)io_request; 5876230557Sjimharris the_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 5877230557Sjimharris 5878230557Sjimharris status = scic_sds_remote_device_complete_io( 5879230557Sjimharris this_controller, the_device, the_request); 5880230557Sjimharris 5881230557Sjimharris if (status == SCI_SUCCESS) 5882230557Sjimharris { 5883230557Sjimharris index = scic_sds_io_tag_get_index(the_request->io_tag); 5884230557Sjimharris this_controller->io_request_table[index] = SCI_INVALID_HANDLE; 5885230557Sjimharris } 5886230557Sjimharris 5887230557Sjimharris return status; 5888230557Sjimharris} 5889230557Sjimharris 5890230557Sjimharris/** 5891230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the ready state 5892230557Sjimharris * and the continue io handler is called. 5893230557Sjimharris * 5894230557Sjimharris * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast 5895230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 5896230557Sjimharris * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a 5897230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 5898230557Sjimharris * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a 5899230557Sjimharris * SCIC_SDS_IO_REQUEST object. 5900230557Sjimharris * 5901230557Sjimharris * @return SCI_STATUS 5902230557Sjimharris */ 5903230557Sjimharrisstatic 5904230557SjimharrisSCI_STATUS scic_sds_controller_ready_state_continue_io_handler( 5905230557Sjimharris SCI_BASE_CONTROLLER_T *controller, 5906230557Sjimharris SCI_BASE_REMOTE_DEVICE_T *remote_device, 5907230557Sjimharris SCI_BASE_REQUEST_T *io_request 5908230557Sjimharris) 5909230557Sjimharris{ 5910230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 5911230557Sjimharris SCIC_SDS_REQUEST_T *the_request; 5912230557Sjimharris 5913230557Sjimharris the_request = (SCIC_SDS_REQUEST_T *)io_request; 5914230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 5915230557Sjimharris 5916230557Sjimharris this_controller->io_request_table[ 5917230557Sjimharris scic_sds_io_tag_get_index(the_request->io_tag)] = the_request; 5918230557Sjimharris 5919230557Sjimharris scic_sds_controller_post_request( 5920230557Sjimharris this_controller, 5921230557Sjimharris scic_sds_request_get_post_context(the_request) 5922230557Sjimharris ); 5923230557Sjimharris 5924230557Sjimharris return SCI_SUCCESS; 5925230557Sjimharris} 5926230557Sjimharris 5927230557Sjimharris/** 5928230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the ready state 5929230557Sjimharris * and the start task handler is called. 5930230557Sjimharris * - The remote device is requested to start the task request 5931230557Sjimharris * - if successful 5932230557Sjimharris * - assign the task to the io_request_table 5933230557Sjimharris * - post the request to the SCU hardware 5934230557Sjimharris * 5935230557Sjimharris * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast 5936230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 5937230557Sjimharris * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a 5938230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 5939230557Sjimharris * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a 5940230557Sjimharris * SCIC_SDS_IO_REQUEST object. 5941230557Sjimharris * @param[in] task_tag This is the task tag to be assigned to the task request 5942230557Sjimharris * or SCI_CONTROLLER_INVALID_IO_TAG. 5943230557Sjimharris * 5944230557Sjimharris * @return SCI_STATUS 5945230557Sjimharris * @retval SCI_SUCCESS if the start io operation succeeds 5946230557Sjimharris * @retval SCI_FAILURE_INSUFFICIENT_RESOURCES if the IO tag could not be 5947230557Sjimharris * allocated for the io request. 5948230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid 5949230557Sjimharris * state to accept io requests. 5950230557Sjimharris * 5951230557Sjimharris * @todo How does the io tag get assigned in this code path? 5952230557Sjimharris */ 5953230557Sjimharrisstatic 5954230557SjimharrisSCI_STATUS scic_sds_controller_ready_state_start_task_handler( 5955230557Sjimharris SCI_BASE_CONTROLLER_T *controller, 5956230557Sjimharris SCI_BASE_REMOTE_DEVICE_T *remote_device, 5957230557Sjimharris SCI_BASE_REQUEST_T *io_request, 5958230557Sjimharris U16 task_tag 5959230557Sjimharris) 5960230557Sjimharris{ 5961230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T *) 5962230557Sjimharris controller; 5963230557Sjimharris SCIC_SDS_REQUEST_T *the_request = (SCIC_SDS_REQUEST_T *) 5964230557Sjimharris io_request; 5965230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T *the_device = (SCIC_SDS_REMOTE_DEVICE_T *) 5966230557Sjimharris remote_device; 5967230557Sjimharris SCI_STATUS status; 5968230557Sjimharris 5969230557Sjimharris status = scic_sds_remote_device_start_task( 5970230557Sjimharris this_controller, the_device, the_request 5971230557Sjimharris ); 5972230557Sjimharris 5973230557Sjimharris if (status == SCI_SUCCESS) 5974230557Sjimharris { 5975230557Sjimharris this_controller->io_request_table[ 5976230557Sjimharris scic_sds_io_tag_get_index(the_request->io_tag)] = the_request; 5977230557Sjimharris 5978230557Sjimharris scic_sds_controller_post_request( 5979230557Sjimharris this_controller, 5980230557Sjimharris scic_sds_request_get_post_context(the_request) 5981230557Sjimharris ); 5982230557Sjimharris } 5983230557Sjimharris else if (status == SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS) 5984230557Sjimharris { 5985230557Sjimharris this_controller->io_request_table[ 5986230557Sjimharris scic_sds_io_tag_get_index(the_request->io_tag)] = the_request; 5987230557Sjimharris 5988230557Sjimharris //We will let framework know this task request started successfully, 5989230557Sjimharris //although core is still woring on starting the request (to post tc when 5990230557Sjimharris //RNC is resumed.) 5991230557Sjimharris status = SCI_SUCCESS; 5992230557Sjimharris } 5993230557Sjimharris return status; 5994230557Sjimharris} 5995230557Sjimharris 5996230557Sjimharris/** 5997230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the ready state 5998230557Sjimharris * and the terminate request handler is called. 5999230557Sjimharris * - call the io request terminate function 6000230557Sjimharris * - if successful 6001230557Sjimharris * - post the terminate request to the SCU hardware 6002230557Sjimharris * 6003230557Sjimharris * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast 6004230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 6005230557Sjimharris * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a 6006230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 6007230557Sjimharris * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a 6008230557Sjimharris * SCIC_SDS_IO_REQUEST object. 6009230557Sjimharris * 6010230557Sjimharris * @return SCI_STATUS 6011230557Sjimharris * @retval SCI_SUCCESS if the start io operation succeeds 6012230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid 6013230557Sjimharris * state to accept io requests. 6014230557Sjimharris */ 6015230557Sjimharrisstatic 6016230557SjimharrisSCI_STATUS scic_sds_controller_ready_state_terminate_request_handler( 6017230557Sjimharris SCI_BASE_CONTROLLER_T *controller, 6018230557Sjimharris SCI_BASE_REMOTE_DEVICE_T *remote_device, 6019230557Sjimharris SCI_BASE_REQUEST_T *io_request 6020230557Sjimharris) 6021230557Sjimharris{ 6022230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T *) 6023230557Sjimharris controller; 6024230557Sjimharris SCIC_SDS_REQUEST_T *the_request = (SCIC_SDS_REQUEST_T *) 6025230557Sjimharris io_request; 6026230557Sjimharris SCI_STATUS status; 6027230557Sjimharris 6028230557Sjimharris status = scic_sds_io_request_terminate(the_request); 6029230557Sjimharris if (status == SCI_SUCCESS) 6030230557Sjimharris { 6031230557Sjimharris // Utilize the original post context command and or in the POST_TC_ABORT 6032230557Sjimharris // request sub-type. 6033230557Sjimharris scic_sds_controller_post_request( 6034230557Sjimharris this_controller, 6035230557Sjimharris scic_sds_request_get_post_context(the_request) 6036230557Sjimharris | SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT 6037230557Sjimharris ); 6038230557Sjimharris } 6039230557Sjimharris 6040230557Sjimharris return status; 6041230557Sjimharris} 6042230557Sjimharris 6043230557Sjimharris/** 6044230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the starting state 6045230557Sjimharris * link up handler is called. This method will perform the following: 6046230557Sjimharris * - Stop the phy timer 6047230557Sjimharris * - Start the next phy 6048230557Sjimharris * - Report the link up condition to the port object 6049230557Sjimharris * 6050230557Sjimharris * @param[in] controller This is SCIC_SDS_CONTROLLER which receives the link up 6051230557Sjimharris * notification. 6052230557Sjimharris * @param[in] port This is SCIC_SDS_PORT with which the phy is associated. 6053230557Sjimharris * @param[in] phy This is the SCIC_SDS_PHY which has gone link up. 6054230557Sjimharris * 6055230557Sjimharris * @return none 6056230557Sjimharris */ 6057230557Sjimharrisstatic 6058230557Sjimharrisvoid scic_sds_controller_ready_state_link_up_handler( 6059230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 6060230557Sjimharris SCIC_SDS_PORT_T *port, 6061230557Sjimharris SCIC_SDS_PHY_T *phy 6062230557Sjimharris) 6063230557Sjimharris{ 6064230557Sjimharris this_controller->port_agent.link_up_handler( 6065230557Sjimharris this_controller, &this_controller->port_agent, port, phy 6066230557Sjimharris ); 6067230557Sjimharris} 6068230557Sjimharris 6069230557Sjimharris/** 6070230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the starting state 6071230557Sjimharris * link down handler is called. 6072230557Sjimharris * - Report the link down condition to the port object 6073230557Sjimharris * 6074230557Sjimharris * @param[in] controller This is SCIC_SDS_CONTROLLER which receives the 6075230557Sjimharris * link down notification. 6076230557Sjimharris * @param[in] port This is SCIC_SDS_PORT with which the phy is associated. 6077230557Sjimharris * @param[in] phy This is the SCIC_SDS_PHY which has gone link down. 6078230557Sjimharris * 6079230557Sjimharris * @return none 6080230557Sjimharris */ 6081230557Sjimharrisstatic 6082230557Sjimharrisvoid scic_sds_controller_ready_state_link_down_handler( 6083230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 6084230557Sjimharris SCIC_SDS_PORT_T *port, 6085230557Sjimharris SCIC_SDS_PHY_T *phy 6086230557Sjimharris) 6087230557Sjimharris{ 6088230557Sjimharris this_controller->port_agent.link_down_handler( 6089230557Sjimharris this_controller, &this_controller->port_agent, port, phy 6090230557Sjimharris ); 6091230557Sjimharris} 6092230557Sjimharris 6093230557Sjimharris//***************************************************************************** 6094230557Sjimharris//* STOPPING STATE HANDLERS 6095230557Sjimharris//***************************************************************************** 6096230557Sjimharris 6097230557Sjimharris/** 6098230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in a stopping state 6099230557Sjimharris * and the complete io handler is called. 6100230557Sjimharris * - This function is not yet implemented 6101230557Sjimharris * 6102230557Sjimharris * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast 6103230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 6104230557Sjimharris * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a 6105230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 6106230557Sjimharris * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a 6107230557Sjimharris * SCIC_SDS_IO_REQUEST object. 6108230557Sjimharris * 6109230557Sjimharris * @return SCI_STATUS 6110230557Sjimharris * @retval SCI_FAILURE 6111230557Sjimharris */ 6112230557Sjimharrisstatic 6113230557SjimharrisSCI_STATUS scic_sds_controller_stopping_state_complete_io_handler( 6114230557Sjimharris SCI_BASE_CONTROLLER_T *controller, 6115230557Sjimharris SCI_BASE_REMOTE_DEVICE_T *remote_device, 6116230557Sjimharris SCI_BASE_REQUEST_T *io_request 6117230557Sjimharris) 6118230557Sjimharris{ 6119230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6120230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 6121230557Sjimharris 6122230557Sjimharris /// @todo Implement this function 6123230557Sjimharris return SCI_FAILURE; 6124230557Sjimharris} 6125230557Sjimharris 6126230557Sjimharris/** 6127230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in a stopping state 6128230557Sjimharris * and the a remote device has stopped. 6129230557Sjimharris * 6130230557Sjimharris * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast 6131230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 6132230557Sjimharris * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a 6133230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 6134230557Sjimharris * 6135230557Sjimharris * @return none 6136230557Sjimharris */ 6137230557Sjimharrisstatic 6138230557Sjimharrisvoid scic_sds_controller_stopping_state_device_stopped_handler( 6139230557Sjimharris SCIC_SDS_CONTROLLER_T * controller, 6140230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * remote_device 6141230557Sjimharris) 6142230557Sjimharris{ 6143230557Sjimharris if (!scic_sds_controller_has_remote_devices_stopping(controller)) 6144230557Sjimharris { 6145230557Sjimharris sci_base_state_machine_change_state( 6146230557Sjimharris &controller->parent.state_machine, 6147230557Sjimharris SCI_BASE_CONTROLLER_STATE_STOPPED 6148230557Sjimharris ); 6149230557Sjimharris } 6150230557Sjimharris} 6151230557Sjimharris 6152230557Sjimharris//***************************************************************************** 6153230557Sjimharris//* STOPPED STATE HANDLERS 6154230557Sjimharris//***************************************************************************** 6155230557Sjimharris 6156230557Sjimharris//***************************************************************************** 6157230557Sjimharris//* FAILED STATE HANDLERS 6158230557Sjimharris//***************************************************************************** 6159230557Sjimharris 6160230557Sjimharris/** 6161230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER failed state start 6162230557Sjimharris * io/task handler is in place. 6163230557Sjimharris * - Issue a warning message 6164230557Sjimharris * 6165230557Sjimharris * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast 6166230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 6167230557Sjimharris * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which, if it was 6168230557Sjimharris * used, would be cast to a SCIC_SDS_REMOTE_DEVICE. 6169230557Sjimharris * @param[in] io_request This is the SCI_BASE_REQUEST which, if it was used, 6170230557Sjimharris * would be cast to a SCIC_SDS_IO_REQUEST. 6171230557Sjimharris * @param[in] io_tag This is the IO tag to be assigned to the IO request or 6172230557Sjimharris * SCI_CONTROLLER_INVALID_IO_TAG. 6173230557Sjimharris * 6174230557Sjimharris * @return SCI_FAILURE 6175230557Sjimharris * @retval SCI_FAILURE 6176230557Sjimharris */ 6177230557Sjimharrisstatic 6178230557SjimharrisSCI_STATUS scic_sds_controller_failed_state_start_operation_handler( 6179230557Sjimharris SCI_BASE_CONTROLLER_T *controller, 6180230557Sjimharris SCI_BASE_REMOTE_DEVICE_T *remote_device, 6181230557Sjimharris SCI_BASE_REQUEST_T *io_request, 6182230557Sjimharris U16 io_tag 6183230557Sjimharris) 6184230557Sjimharris{ 6185230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6186230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 6187230557Sjimharris 6188230557Sjimharris SCIC_LOG_WARNING(( 6189230557Sjimharris sci_base_object_get_logger(this_controller), 6190230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 6191230557Sjimharris "SCIC Controller requested to start an io/task from failed state %d\n", 6192230557Sjimharris sci_base_state_machine_get_state( 6193230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller)) 6194230557Sjimharris )); 6195230557Sjimharris 6196230557Sjimharris return SCI_FAILURE; 6197230557Sjimharris} 6198230557Sjimharris 6199230557Sjimharris/** 6200230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the failed state 6201230557Sjimharris * reset handler is in place. 6202230557Sjimharris * - Transition to SCI_BASE_CONTROLLER_STATE_RESETTING 6203230557Sjimharris * 6204230557Sjimharris * @param[in] controller The SCI_BASE_CONTROLLER object which is cast into a 6205230557Sjimharris * SCIC_SDS_CONTROLLER object. 6206230557Sjimharris * 6207230557Sjimharris * @return SCI_STATUS 6208230557Sjimharris * @retval SCI_FAILURE if fatal memory error occurred 6209230557Sjimharris */ 6210230557Sjimharrisstatic 6211230557SjimharrisSCI_STATUS scic_sds_controller_failed_state_reset_handler( 6212230557Sjimharris SCI_BASE_CONTROLLER_T *controller 6213230557Sjimharris) 6214230557Sjimharris{ 6215230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6216230557Sjimharris this_controller = (SCIC_SDS_CONTROLLER_T *)controller; 6217230557Sjimharris 6218230557Sjimharris if (this_controller->parent.error == SCI_CONTROLLER_FATAL_MEMORY_ERROR) { 6219230557Sjimharris SCIC_LOG_TRACE(( 6220230557Sjimharris sci_base_object_get_logger(controller), 6221230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 6222230557Sjimharris "scic_sds_controller_resetting_state_enter(0x%x) enter\n not allowed with fatal memory error", 6223230557Sjimharris controller 6224230557Sjimharris )); 6225230557Sjimharris 6226230557Sjimharris return SCI_FAILURE; 6227230557Sjimharris } else { 6228230557Sjimharris return scic_sds_controller_general_reset_handler(controller); 6229230557Sjimharris } 6230230557Sjimharris} 6231230557Sjimharris 6232230557Sjimharris/** 6233230557Sjimharris * This method is called when the SCIC_SDS_CONTROLLER is in the failed state 6234230557Sjimharris * and the terminate request handler is called. 6235230557Sjimharris * - call the io request terminate function 6236230557Sjimharris * - if successful 6237230557Sjimharris * - post the terminate request to the SCU hardware 6238230557Sjimharris * 6239230557Sjimharris * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast 6240230557Sjimharris * into a SCIC_SDS_CONTROLLER object. 6241230557Sjimharris * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a 6242230557Sjimharris * SCIC_SDS_REMOTE_DEVICE object. 6243230557Sjimharris * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a 6244230557Sjimharris * SCIC_SDS_IO_REQUEST object. 6245230557Sjimharris * 6246230557Sjimharris * @return SCI_STATUS 6247230557Sjimharris * @retval SCI_SUCCESS if the start io operation succeeds 6248230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid 6249230557Sjimharris * state to accept io requests. 6250230557Sjimharris */ 6251230557Sjimharrisstatic 6252230557SjimharrisSCI_STATUS scic_sds_controller_failed_state_terminate_request_handler( 6253230557Sjimharris SCI_BASE_CONTROLLER_T *controller, 6254230557Sjimharris SCI_BASE_REMOTE_DEVICE_T *remote_device, 6255230557Sjimharris SCI_BASE_REQUEST_T *io_request 6256230557Sjimharris) 6257230557Sjimharris{ 6258230557Sjimharris SCIC_SDS_REQUEST_T *the_request = (SCIC_SDS_REQUEST_T *) 6259230557Sjimharris io_request; 6260230557Sjimharris 6261230557Sjimharris return scic_sds_io_request_terminate(the_request); 6262230557Sjimharris} 6263230557Sjimharris 6264230557SjimharrisSCIC_SDS_CONTROLLER_STATE_HANDLER_T 6265230557Sjimharris scic_sds_controller_state_handler_table[SCI_BASE_CONTROLLER_MAX_STATES] = 6266230557Sjimharris{ 6267230557Sjimharris // SCI_BASE_CONTROLLER_STATE_INITIAL 6268230557Sjimharris { 6269230557Sjimharris { 6270230557Sjimharris NULL, 6271230557Sjimharris NULL, 6272230557Sjimharris NULL, 6273230557Sjimharris NULL, 6274230557Sjimharris scic_sds_controller_default_start_operation_handler, 6275230557Sjimharris scic_sds_controller_default_start_operation_handler, 6276230557Sjimharris scic_sds_controller_default_request_handler, 6277230557Sjimharris scic_sds_controller_default_request_handler, 6278230557Sjimharris scic_sds_controller_default_request_handler, 6279230557Sjimharris NULL, 6280230557Sjimharris NULL 6281230557Sjimharris }, 6282230557Sjimharris scic_sds_controller_default_request_handler, 6283230557Sjimharris NULL, 6284230557Sjimharris NULL, 6285230557Sjimharris NULL, 6286230557Sjimharris NULL 6287230557Sjimharris }, 6288230557Sjimharris // SCI_BASE_CONTROLLER_STATE_RESET 6289230557Sjimharris { 6290230557Sjimharris { 6291230557Sjimharris NULL, 6292230557Sjimharris NULL, 6293230557Sjimharris NULL, 6294230557Sjimharris scic_sds_controller_reset_state_initialize_handler, 6295230557Sjimharris scic_sds_controller_default_start_operation_handler, 6296230557Sjimharris scic_sds_controller_default_start_operation_handler, 6297230557Sjimharris scic_sds_controller_default_request_handler, 6298230557Sjimharris scic_sds_controller_default_request_handler, 6299230557Sjimharris scic_sds_controller_default_request_handler, 6300230557Sjimharris NULL, 6301230557Sjimharris NULL 6302230557Sjimharris }, 6303230557Sjimharris scic_sds_controller_default_request_handler, 6304230557Sjimharris NULL, 6305230557Sjimharris NULL, 6306230557Sjimharris NULL, 6307230557Sjimharris NULL 6308230557Sjimharris }, 6309230557Sjimharris // SCI_BASE_CONTROLLER_STATE_INITIALIZING 6310230557Sjimharris { 6311230557Sjimharris { 6312230557Sjimharris NULL, 6313230557Sjimharris NULL, 6314230557Sjimharris NULL, 6315230557Sjimharris NULL, 6316230557Sjimharris scic_sds_controller_default_start_operation_handler, 6317230557Sjimharris scic_sds_controller_default_start_operation_handler, 6318230557Sjimharris scic_sds_controller_default_request_handler, 6319230557Sjimharris scic_sds_controller_default_request_handler, 6320230557Sjimharris scic_sds_controller_default_request_handler, 6321230557Sjimharris NULL, 6322230557Sjimharris NULL 6323230557Sjimharris }, 6324230557Sjimharris scic_sds_controller_default_request_handler, 6325230557Sjimharris NULL, 6326230557Sjimharris NULL, 6327230557Sjimharris NULL, 6328230557Sjimharris NULL 6329230557Sjimharris }, 6330230557Sjimharris // SCI_BASE_CONTROLLER_STATE_INITIALIZED 6331230557Sjimharris { 6332230557Sjimharris { 6333230557Sjimharris scic_sds_controller_initialized_state_start_handler, 6334230557Sjimharris NULL, 6335230557Sjimharris NULL, 6336230557Sjimharris NULL, 6337230557Sjimharris scic_sds_controller_default_start_operation_handler, 6338230557Sjimharris scic_sds_controller_default_start_operation_handler, 6339230557Sjimharris scic_sds_controller_default_request_handler, 6340230557Sjimharris scic_sds_controller_default_request_handler, 6341230557Sjimharris scic_sds_controller_default_request_handler, 6342230557Sjimharris NULL, 6343230557Sjimharris NULL 6344230557Sjimharris }, 6345230557Sjimharris scic_sds_controller_default_request_handler, 6346230557Sjimharris NULL, 6347230557Sjimharris NULL, 6348230557Sjimharris NULL, 6349230557Sjimharris NULL 6350230557Sjimharris }, 6351230557Sjimharris // SCI_BASE_CONTROLLER_STATE_STARTING 6352230557Sjimharris { 6353230557Sjimharris { 6354230557Sjimharris NULL, 6355230557Sjimharris NULL, 6356230557Sjimharris NULL, 6357230557Sjimharris NULL, 6358230557Sjimharris scic_sds_controller_default_start_operation_handler, 6359230557Sjimharris scic_sds_controller_default_start_operation_handler, 6360230557Sjimharris scic_sds_controller_default_request_handler, 6361230557Sjimharris scic_sds_controller_default_request_handler, 6362230557Sjimharris scic_sds_controller_default_request_handler, 6363230557Sjimharris NULL, 6364230557Sjimharris NULL 6365230557Sjimharris }, 6366230557Sjimharris scic_sds_controller_default_request_handler, 6367230557Sjimharris scic_sds_controller_starting_state_link_up_handler, 6368230557Sjimharris scic_sds_controller_starting_state_link_down_handler, 6369230557Sjimharris NULL, 6370230557Sjimharris NULL 6371230557Sjimharris }, 6372230557Sjimharris // SCI_BASE_CONTROLLER_STATE_READY 6373230557Sjimharris { 6374230557Sjimharris { 6375230557Sjimharris NULL, 6376230557Sjimharris scic_sds_controller_ready_state_stop_handler, 6377230557Sjimharris scic_sds_controller_general_reset_handler, 6378230557Sjimharris NULL, 6379230557Sjimharris scic_sds_controller_ready_state_start_io_handler, 6380230557Sjimharris scic_sds_controller_default_start_operation_handler, 6381230557Sjimharris scic_sds_controller_ready_state_complete_io_handler, 6382230557Sjimharris scic_sds_controller_default_request_handler, 6383230557Sjimharris scic_sds_controller_ready_state_continue_io_handler, 6384230557Sjimharris scic_sds_controller_ready_state_start_task_handler, 6385230557Sjimharris scic_sds_controller_ready_state_complete_io_handler 6386230557Sjimharris }, 6387230557Sjimharris scic_sds_controller_ready_state_terminate_request_handler, 6388230557Sjimharris scic_sds_controller_ready_state_link_up_handler, 6389230557Sjimharris scic_sds_controller_ready_state_link_down_handler, 6390230557Sjimharris NULL, 6391230557Sjimharris NULL 6392230557Sjimharris }, 6393230557Sjimharris // SCI_BASE_CONTROLLER_STATE_RESETTING 6394230557Sjimharris { 6395230557Sjimharris { 6396230557Sjimharris NULL, 6397230557Sjimharris NULL, 6398230557Sjimharris NULL, 6399230557Sjimharris NULL, 6400230557Sjimharris scic_sds_controller_default_start_operation_handler, 6401230557Sjimharris scic_sds_controller_default_start_operation_handler, 6402230557Sjimharris scic_sds_controller_default_request_handler, 6403230557Sjimharris scic_sds_controller_default_request_handler, 6404230557Sjimharris scic_sds_controller_default_request_handler, 6405230557Sjimharris NULL, 6406230557Sjimharris NULL 6407230557Sjimharris }, 6408230557Sjimharris scic_sds_controller_default_request_handler, 6409230557Sjimharris NULL, 6410230557Sjimharris NULL, 6411230557Sjimharris NULL, 6412230557Sjimharris NULL 6413230557Sjimharris }, 6414230557Sjimharris // SCI_BASE_CONTROLLER_STATE_STOPPING 6415230557Sjimharris { 6416230557Sjimharris { 6417230557Sjimharris NULL, 6418230557Sjimharris NULL, 6419230557Sjimharris NULL, 6420230557Sjimharris NULL, 6421230557Sjimharris scic_sds_controller_default_start_operation_handler, 6422230557Sjimharris scic_sds_controller_default_start_operation_handler, 6423230557Sjimharris scic_sds_controller_stopping_state_complete_io_handler, 6424230557Sjimharris scic_sds_controller_default_request_handler, 6425230557Sjimharris scic_sds_controller_default_request_handler, 6426230557Sjimharris NULL, 6427230557Sjimharris NULL 6428230557Sjimharris }, 6429230557Sjimharris scic_sds_controller_default_request_handler, 6430230557Sjimharris NULL, 6431230557Sjimharris NULL, 6432230557Sjimharris NULL, 6433230557Sjimharris scic_sds_controller_stopping_state_device_stopped_handler 6434230557Sjimharris }, 6435230557Sjimharris // SCI_BASE_CONTROLLER_STATE_STOPPED 6436230557Sjimharris { 6437230557Sjimharris { 6438230557Sjimharris NULL, 6439230557Sjimharris NULL, 6440230557Sjimharris scic_sds_controller_failed_state_reset_handler, 6441230557Sjimharris NULL, 6442230557Sjimharris scic_sds_controller_default_start_operation_handler, 6443230557Sjimharris scic_sds_controller_default_start_operation_handler, 6444230557Sjimharris scic_sds_controller_default_request_handler, 6445230557Sjimharris scic_sds_controller_default_request_handler, 6446230557Sjimharris scic_sds_controller_default_request_handler, 6447230557Sjimharris NULL, 6448230557Sjimharris NULL 6449230557Sjimharris }, 6450230557Sjimharris scic_sds_controller_default_request_handler, 6451230557Sjimharris NULL, 6452230557Sjimharris NULL, 6453230557Sjimharris NULL, 6454230557Sjimharris NULL 6455230557Sjimharris }, 6456230557Sjimharris // SCI_BASE_CONTROLLER_STATE_FAILED 6457230557Sjimharris { 6458230557Sjimharris { 6459230557Sjimharris NULL, 6460230557Sjimharris NULL, 6461230557Sjimharris scic_sds_controller_general_reset_handler, 6462230557Sjimharris NULL, 6463230557Sjimharris scic_sds_controller_failed_state_start_operation_handler, 6464230557Sjimharris scic_sds_controller_failed_state_start_operation_handler, 6465230557Sjimharris scic_sds_controller_default_request_handler, 6466230557Sjimharris scic_sds_controller_default_request_handler, 6467230557Sjimharris scic_sds_controller_default_request_handler, 6468230557Sjimharris NULL, 6469230557Sjimharris NULL 6470230557Sjimharris }, 6471230557Sjimharris scic_sds_controller_failed_state_terminate_request_handler, 6472230557Sjimharris NULL, 6473230557Sjimharris NULL, 6474230557Sjimharris NULL 6475230557Sjimharris } 6476230557Sjimharris}; 6477230557Sjimharris 6478230557Sjimharris/** 6479230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on 6480230557Sjimharris * entry to the SCI_BASE_CONTROLLER_STATE_INITIAL. 6481230557Sjimharris * - Set the state handlers to the controllers initial state. 6482230557Sjimharris * 6483230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6484230557Sjimharris * SCIC_SDS_CONTROLLER object. 6485230557Sjimharris * 6486230557Sjimharris * @return none 6487230557Sjimharris * 6488230557Sjimharris * @todo This function should initialze the controller object. 6489230557Sjimharris */ 6490230557Sjimharrisstatic 6491230557Sjimharrisvoid scic_sds_controller_initial_state_enter( 6492230557Sjimharris SCI_BASE_OBJECT_T *object 6493230557Sjimharris) 6494230557Sjimharris{ 6495230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6496230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6497230557Sjimharris 6498230557Sjimharris scic_sds_controller_set_base_state_handlers( 6499230557Sjimharris this_controller, SCI_BASE_CONTROLLER_STATE_INITIAL); 6500230557Sjimharris 6501230557Sjimharris sci_base_state_machine_change_state( 6502230557Sjimharris &this_controller->parent.state_machine, SCI_BASE_CONTROLLER_STATE_RESET); 6503230557Sjimharris} 6504230557Sjimharris 6505230557Sjimharris/** 6506230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on 6507230557Sjimharris * entry to the SCI_BASE_CONTROLLER_STATE_RESET. 6508230557Sjimharris * - Set the state handlers to the controllers reset state. 6509230557Sjimharris * 6510230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6511230557Sjimharris * SCIC_SDS_CONTROLLER object. 6512230557Sjimharris * 6513230557Sjimharris * @return none 6514230557Sjimharris */ 6515230557Sjimharrisstatic 6516230557Sjimharrisvoid scic_sds_controller_reset_state_enter( 6517230557Sjimharris SCI_BASE_OBJECT_T *object 6518230557Sjimharris) 6519230557Sjimharris{ 6520230557Sjimharris U8 index; 6521230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6522230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6523230557Sjimharris 6524230557Sjimharris scic_sds_controller_set_base_state_handlers( 6525230557Sjimharris this_controller, SCI_BASE_CONTROLLER_STATE_RESET); 6526230557Sjimharris 6527230557Sjimharris scic_sds_port_configuration_agent_construct(&this_controller->port_agent); 6528230557Sjimharris 6529230557Sjimharris // Construct the ports for this controller 6530230557Sjimharris for (index = 0; index < (SCI_MAX_PORTS + 1); index++) 6531230557Sjimharris { 6532230557Sjimharris scic_sds_port_construct( 6533230557Sjimharris &this_controller->port_table[index], 6534230557Sjimharris (index == SCI_MAX_PORTS) ? SCIC_SDS_DUMMY_PORT : index, 6535230557Sjimharris this_controller 6536230557Sjimharris ); 6537230557Sjimharris } 6538230557Sjimharris 6539230557Sjimharris // Construct the phys for this controller 6540230557Sjimharris for (index = 0; index < SCI_MAX_PHYS; index++) 6541230557Sjimharris { 6542230557Sjimharris // Add all the PHYs to the dummy port 6543230557Sjimharris scic_sds_phy_construct( 6544230557Sjimharris &this_controller->phy_table[index], 6545230557Sjimharris &this_controller->port_table[SCI_MAX_PORTS], 6546230557Sjimharris index 6547230557Sjimharris ); 6548230557Sjimharris } 6549230557Sjimharris 6550230557Sjimharris this_controller->invalid_phy_mask = 0; 6551230557Sjimharris 6552230557Sjimharris // Set the default maximum values 6553230557Sjimharris this_controller->completion_event_entries = SCU_EVENT_COUNT; 6554230557Sjimharris this_controller->completion_queue_entries = SCU_COMPLETION_QUEUE_COUNT; 6555230557Sjimharris this_controller->remote_node_entries = SCI_MAX_REMOTE_DEVICES; 6556230557Sjimharris this_controller->logical_port_entries = SCI_MAX_PORTS; 6557230557Sjimharris this_controller->task_context_entries = SCU_IO_REQUEST_COUNT; 6558230557Sjimharris this_controller->uf_control.buffers.count = SCU_UNSOLICITED_FRAME_COUNT; 6559230557Sjimharris this_controller->uf_control.address_table.count= SCU_UNSOLICITED_FRAME_COUNT; 6560230557Sjimharris 6561230557Sjimharris // Initialize the User and OEM parameters to default values. 6562230557Sjimharris scic_sds_controller_set_default_config_parameters(this_controller); 6563230557Sjimharris} 6564230557Sjimharris 6565230557Sjimharris/** 6566230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on 6567230557Sjimharris * entry to the SCI_BASE_CONTROLLER_STATE_INITIALIZING. 6568230557Sjimharris * - Set the state handlers to the controllers initializing state. 6569230557Sjimharris * 6570230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6571230557Sjimharris * SCIC_SDS_CONTROLLER object. 6572230557Sjimharris * 6573230557Sjimharris * @return none 6574230557Sjimharris */ 6575230557Sjimharrisstatic 6576230557Sjimharrisvoid scic_sds_controller_initializing_state_enter( 6577230557Sjimharris SCI_BASE_OBJECT_T *object 6578230557Sjimharris) 6579230557Sjimharris{ 6580230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6581230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6582230557Sjimharris 6583230557Sjimharris scic_sds_controller_set_base_state_handlers( 6584230557Sjimharris this_controller, SCI_BASE_CONTROLLER_STATE_INITIALIZING); 6585230557Sjimharris} 6586230557Sjimharris 6587230557Sjimharris/** 6588230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on 6589230557Sjimharris * entry to the SCI_BASE_CONTROLLER_STATE_INITIALIZED. 6590230557Sjimharris * - Set the state handlers to the controllers initialized state. 6591230557Sjimharris * 6592230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6593230557Sjimharris * SCIC_SDS_CONTROLLER object. 6594230557Sjimharris * 6595230557Sjimharris * @return none 6596230557Sjimharris */ 6597230557Sjimharrisstatic 6598230557Sjimharrisvoid scic_sds_controller_initialized_state_enter( 6599230557Sjimharris SCI_BASE_OBJECT_T *object 6600230557Sjimharris) 6601230557Sjimharris{ 6602230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6603230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6604230557Sjimharris 6605230557Sjimharris scic_sds_controller_set_base_state_handlers( 6606230557Sjimharris this_controller, SCI_BASE_CONTROLLER_STATE_INITIALIZED); 6607230557Sjimharris} 6608230557Sjimharris 6609230557Sjimharris/** 6610230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on 6611230557Sjimharris * entry to the SCI_BASE_CONTROLLER_STATE_STARTING. 6612230557Sjimharris * - Set the state handlers to the controllers starting state. 6613230557Sjimharris * 6614230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6615230557Sjimharris * SCIC_SDS_CONTROLLER object. 6616230557Sjimharris * 6617230557Sjimharris * @return none 6618230557Sjimharris */ 6619230557Sjimharrisstatic 6620230557Sjimharrisvoid scic_sds_controller_starting_state_enter( 6621230557Sjimharris SCI_BASE_OBJECT_T *object 6622230557Sjimharris) 6623230557Sjimharris{ 6624230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6625230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6626230557Sjimharris 6627230557Sjimharris scic_sds_controller_set_base_state_handlers( 6628230557Sjimharris this_controller, SCI_BASE_CONTROLLER_STATE_STARTING); 6629230557Sjimharris 6630230557Sjimharris} 6631230557Sjimharris 6632230557Sjimharris/** 6633230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on exit 6634230557Sjimharris * from the SCI_BASE_CONTROLLER_STATE_STARTING. 6635230557Sjimharris * - This function stops the controller starting timeout timer. 6636230557Sjimharris * 6637230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6638230557Sjimharris * SCIC_SDS_CONTROLLER object. 6639230557Sjimharris * 6640230557Sjimharris * @return none 6641230557Sjimharris */ 6642230557Sjimharrisstatic 6643230557Sjimharrisvoid scic_sds_controller_starting_state_exit( 6644230557Sjimharris SCI_BASE_OBJECT_T *object 6645230557Sjimharris) 6646230557Sjimharris{ 6647230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6648230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6649230557Sjimharris 6650230557Sjimharris scic_cb_timer_stop(object, this_controller->timeout_timer); 6651230557Sjimharris 6652230557Sjimharris // We are done with this timer since we are exiting the starting 6653230557Sjimharris // state so remove it 6654230557Sjimharris scic_cb_timer_destroy( 6655230557Sjimharris this_controller, 6656230557Sjimharris this_controller->phy_startup_timer 6657230557Sjimharris ); 6658230557Sjimharris 6659230557Sjimharris this_controller->phy_startup_timer = NULL; 6660230557Sjimharris} 6661230557Sjimharris 6662230557Sjimharris/** 6663230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on 6664230557Sjimharris * entry to the SCI_BASE_CONTROLLER_STATE_READY. 6665230557Sjimharris * - Set the state handlers to the controllers ready state. 6666230557Sjimharris * 6667230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6668230557Sjimharris * SCIC_SDS_CONTROLLER object. 6669230557Sjimharris * 6670230557Sjimharris * @return none 6671230557Sjimharris */ 6672230557Sjimharrisstatic 6673230557Sjimharrisvoid scic_sds_controller_ready_state_enter( 6674230557Sjimharris SCI_BASE_OBJECT_T *object 6675230557Sjimharris) 6676230557Sjimharris{ 6677230557Sjimharris U32 clock_gating_unit_value; 6678230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6679230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6680230557Sjimharris 6681230557Sjimharris scic_sds_controller_set_base_state_handlers( 6682230557Sjimharris this_controller, SCI_BASE_CONTROLLER_STATE_READY); 6683230557Sjimharris 6684230557Sjimharris /** 6685230557Sjimharris * enable clock gating for power control of the scu unit 6686230557Sjimharris */ 6687230557Sjimharris clock_gating_unit_value = SMU_CGUCR_READ(this_controller); 6688230557Sjimharris 6689230557Sjimharris clock_gating_unit_value &= ~( SMU_CGUCR_GEN_BIT(REGCLK_ENABLE) 6690230557Sjimharris | SMU_CGUCR_GEN_BIT(TXCLK_ENABLE) 6691230557Sjimharris | SMU_CGUCR_GEN_BIT(XCLK_ENABLE) ); 6692230557Sjimharris clock_gating_unit_value |= SMU_CGUCR_GEN_BIT(IDLE_ENABLE); 6693230557Sjimharris 6694230557Sjimharris SMU_CGUCR_WRITE(this_controller, clock_gating_unit_value); 6695230557Sjimharris 6696230557Sjimharris //set the default interrupt coalescence number and timeout value. 6697230557Sjimharris scic_controller_set_interrupt_coalescence( 6698230557Sjimharris this_controller, 0x10, 250); 6699230557Sjimharris} 6700230557Sjimharris 6701230557Sjimharris/** 6702230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on exit 6703230557Sjimharris * from the SCI_BASE_CONTROLLER_STATE_READY. 6704230557Sjimharris * - This function does nothing. 6705230557Sjimharris * 6706230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6707230557Sjimharris * SCIC_SDS_CONTROLLER object. 6708230557Sjimharris * 6709230557Sjimharris * @return none 6710230557Sjimharris */ 6711230557Sjimharrisstatic 6712230557Sjimharrisvoid scic_sds_controller_ready_state_exit( 6713230557Sjimharris SCI_BASE_OBJECT_T *object 6714230557Sjimharris) 6715230557Sjimharris{ 6716230557Sjimharris U32 clock_gating_unit_value; 6717230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6718230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6719230557Sjimharris 6720230557Sjimharris /** 6721230557Sjimharris * restore clock gating for power control of the scu unit 6722230557Sjimharris */ 6723230557Sjimharris clock_gating_unit_value = SMU_CGUCR_READ(this_controller); 6724230557Sjimharris 6725230557Sjimharris clock_gating_unit_value &= ~SMU_CGUCR_GEN_BIT(IDLE_ENABLE); 6726230557Sjimharris clock_gating_unit_value |= ( SMU_CGUCR_GEN_BIT(REGCLK_ENABLE) 6727230557Sjimharris | SMU_CGUCR_GEN_BIT(TXCLK_ENABLE) 6728230557Sjimharris | SMU_CGUCR_GEN_BIT(XCLK_ENABLE) ); 6729230557Sjimharris 6730230557Sjimharris SMU_CGUCR_WRITE(this_controller, clock_gating_unit_value); 6731230557Sjimharris 6732230557Sjimharris //disable interrupt coalescence. 6733230557Sjimharris scic_controller_set_interrupt_coalescence(this_controller, 0, 0); 6734230557Sjimharris} 6735230557Sjimharris 6736230557Sjimharris/** 6737230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on 6738230557Sjimharris * entry to the SCI_BASE_CONTROLLER_STATE_READY. 6739230557Sjimharris * - Set the state handlers to the controllers ready state. 6740230557Sjimharris * - Stop all of the remote devices on this controller 6741230557Sjimharris * - Stop the ports on this controller 6742230557Sjimharris * - Stop the phys on this controller 6743230557Sjimharris * 6744230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6745230557Sjimharris * SCIC_SDS_CONTROLLER object. 6746230557Sjimharris * 6747230557Sjimharris * @return none 6748230557Sjimharris */ 6749230557Sjimharrisstatic 6750230557Sjimharrisvoid scic_sds_controller_stopping_state_enter( 6751230557Sjimharris SCI_BASE_OBJECT_T *object 6752230557Sjimharris) 6753230557Sjimharris{ 6754230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6755230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6756230557Sjimharris 6757230557Sjimharris scic_sds_controller_set_base_state_handlers( 6758230557Sjimharris this_controller, SCI_BASE_CONTROLLER_STATE_STOPPING); 6759230557Sjimharris 6760230557Sjimharris // Stop all of the components for this controller in the reverse order 6761230557Sjimharris // from which they are initialized. 6762230557Sjimharris scic_sds_controller_stop_devices(this_controller); 6763230557Sjimharris scic_sds_controller_stop_ports(this_controller); 6764230557Sjimharris 6765230557Sjimharris if (!scic_sds_controller_has_remote_devices_stopping(this_controller)) 6766230557Sjimharris { 6767230557Sjimharris sci_base_state_machine_change_state( 6768230557Sjimharris &this_controller->parent.state_machine, 6769230557Sjimharris SCI_BASE_CONTROLLER_STATE_STOPPED 6770230557Sjimharris ); 6771230557Sjimharris } 6772230557Sjimharris} 6773230557Sjimharris 6774230557Sjimharris/** 6775230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on exit 6776230557Sjimharris * from the SCI_BASE_CONTROLLER_STATE_STOPPING. 6777230557Sjimharris * - This function stops the controller stopping timeout timer. 6778230557Sjimharris * 6779230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6780230557Sjimharris * SCIC_SDS_CONTROLLER object. 6781230557Sjimharris * 6782230557Sjimharris * @return none 6783230557Sjimharris */ 6784230557Sjimharrisstatic 6785230557Sjimharrisvoid scic_sds_controller_stopping_state_exit( 6786230557Sjimharris SCI_BASE_OBJECT_T *object 6787230557Sjimharris) 6788230557Sjimharris{ 6789230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6790230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6791230557Sjimharris 6792230557Sjimharris scic_cb_timer_stop(this_controller, this_controller->timeout_timer); 6793230557Sjimharris} 6794230557Sjimharris 6795230557Sjimharris/** 6796230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on 6797230557Sjimharris * entry to the SCI_BASE_CONTROLLER_STATE_STOPPED. 6798230557Sjimharris * - Set the state handlers to the controllers stopped state. 6799230557Sjimharris * 6800230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6801230557Sjimharris * SCIC_SDS_CONTROLLER object. 6802230557Sjimharris * 6803230557Sjimharris * @return none 6804230557Sjimharris */ 6805230557Sjimharrisstatic 6806230557Sjimharrisvoid scic_sds_controller_stopped_state_enter( 6807230557Sjimharris SCI_BASE_OBJECT_T *object 6808230557Sjimharris) 6809230557Sjimharris{ 6810230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6811230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6812230557Sjimharris 6813230557Sjimharris scic_sds_controller_set_base_state_handlers( 6814230557Sjimharris this_controller, SCI_BASE_CONTROLLER_STATE_STOPPED); 6815230557Sjimharris 6816230557Sjimharris // We are done with this timer until the next timer we initialize 6817230557Sjimharris scic_cb_timer_destroy( 6818230557Sjimharris this_controller, 6819230557Sjimharris this_controller->timeout_timer 6820230557Sjimharris ); 6821230557Sjimharris this_controller->timeout_timer = NULL; 6822230557Sjimharris 6823230557Sjimharris // Controller has stopped so disable all the phys on this controller 6824230557Sjimharris scic_sds_controller_stop_phys(this_controller); 6825230557Sjimharris 6826230557Sjimharris scic_sds_port_configuration_agent_destroy( 6827230557Sjimharris this_controller, 6828230557Sjimharris &this_controller->port_agent 6829230557Sjimharris ); 6830230557Sjimharris 6831230557Sjimharris scic_cb_controller_stop_complete(this_controller, SCI_SUCCESS); 6832230557Sjimharris} 6833230557Sjimharris 6834230557Sjimharris/** 6835230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on 6836230557Sjimharris * entry to the SCI_BASE_CONTROLLER_STATE_RESETTING. 6837230557Sjimharris * - Set the state handlers to the controllers resetting state. 6838230557Sjimharris * - Write to the SCU hardware reset register to force a reset 6839230557Sjimharris * - Transition to the SCI_BASE_CONTROLLER_STATE_RESET 6840230557Sjimharris * 6841230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6842230557Sjimharris * SCIC_SDS_CONTROLLER object. 6843230557Sjimharris * 6844230557Sjimharris * @return none 6845230557Sjimharris */ 6846230557Sjimharrisstatic 6847230557Sjimharrisvoid scic_sds_controller_resetting_state_enter( 6848230557Sjimharris SCI_BASE_OBJECT_T *object 6849230557Sjimharris) 6850230557Sjimharris{ 6851230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6852230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6853230557Sjimharris 6854230557Sjimharris SCIC_LOG_TRACE(( 6855230557Sjimharris sci_base_object_get_logger(this_controller), 6856230557Sjimharris SCIC_LOG_OBJECT_CONTROLLER, 6857230557Sjimharris "scic_sds_controller_resetting_state_enter(0x%x) enter\n", 6858230557Sjimharris this_controller 6859230557Sjimharris )); 6860230557Sjimharris 6861230557Sjimharris scic_sds_controller_set_base_state_handlers( 6862230557Sjimharris this_controller, SCI_BASE_CONTROLLER_STATE_RESETTING); 6863230557Sjimharris 6864230557Sjimharris scic_sds_controller_reset_hardware(this_controller); 6865230557Sjimharris 6866230557Sjimharris sci_base_state_machine_change_state( 6867230557Sjimharris scic_sds_controller_get_base_state_machine(this_controller), 6868230557Sjimharris SCI_BASE_CONTROLLER_STATE_RESET 6869230557Sjimharris ); 6870230557Sjimharris} 6871230557Sjimharris 6872230557Sjimharrisstatic 6873230557SjimharrisSCI_STATUS scic_sds_abort_reqests( 6874230557Sjimharris SCIC_SDS_CONTROLLER_T * controller, 6875230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * remote_device, 6876230557Sjimharris SCIC_SDS_PORT_T * port 6877230557Sjimharris) 6878230557Sjimharris{ 6879230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 6880230557Sjimharris SCI_STATUS terminate_status = SCI_SUCCESS; 6881230557Sjimharris SCIC_SDS_REQUEST_T *the_request; 6882230557Sjimharris U32 index; 6883230557Sjimharris U32 request_count; 6884230557Sjimharris 6885230557Sjimharris if (remote_device != NULL) 6886230557Sjimharris request_count = remote_device->started_request_count; 6887230557Sjimharris else if (port != NULL) 6888230557Sjimharris request_count = port->started_request_count; 6889230557Sjimharris else 6890230557Sjimharris request_count = SCI_MAX_IO_REQUESTS; 6891230557Sjimharris 6892230557Sjimharris 6893230557Sjimharris for (index = 0; 6894230557Sjimharris (index < SCI_MAX_IO_REQUESTS) && (request_count > 0); 6895230557Sjimharris index++) 6896230557Sjimharris { 6897230557Sjimharris the_request = controller->io_request_table[index]; 6898230557Sjimharris 6899230557Sjimharris if (the_request != NULL) 6900230557Sjimharris { 6901230557Sjimharris if (the_request->target_device == remote_device 6902230557Sjimharris || the_request->target_device->owning_port == port 6903230557Sjimharris || (remote_device == NULL && port == NULL)) 6904230557Sjimharris { 6905230557Sjimharris terminate_status = scic_controller_terminate_request( 6906230557Sjimharris controller, 6907230557Sjimharris the_request->target_device, 6908230557Sjimharris the_request 6909230557Sjimharris ); 6910230557Sjimharris 6911230557Sjimharris if (terminate_status != SCI_SUCCESS) 6912230557Sjimharris status = terminate_status; 6913230557Sjimharris 6914230557Sjimharris request_count--; 6915230557Sjimharris } 6916230557Sjimharris } 6917230557Sjimharris } 6918230557Sjimharris 6919230557Sjimharris return status; 6920230557Sjimharris} 6921230557Sjimharris 6922230557SjimharrisSCI_STATUS scic_sds_terminate_reqests( 6923230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller, 6924230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T *this_remote_device, 6925230557Sjimharris SCIC_SDS_PORT_T *this_port 6926230557Sjimharris) 6927230557Sjimharris{ 6928230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 6929230557Sjimharris SCI_STATUS abort_status = SCI_SUCCESS; 6930230557Sjimharris 6931230557Sjimharris // move all request to abort state 6932230557Sjimharris abort_status = scic_sds_abort_reqests(this_controller, this_remote_device, this_port); 6933230557Sjimharris 6934230557Sjimharris if (abort_status != SCI_SUCCESS) 6935230557Sjimharris status = abort_status; 6936230557Sjimharris 6937230557Sjimharris //move all request to complete state 6938230557Sjimharris if (this_controller->parent.error == SCI_CONTROLLER_FATAL_MEMORY_ERROR) 6939230557Sjimharris abort_status = scic_sds_abort_reqests(this_controller, this_remote_device, this_port); 6940230557Sjimharris 6941230557Sjimharris if (abort_status != SCI_SUCCESS) 6942230557Sjimharris status = abort_status; 6943230557Sjimharris 6944230557Sjimharris return status; 6945230557Sjimharris} 6946230557Sjimharris 6947230557Sjimharrisstatic 6948230557SjimharrisSCI_STATUS scic_sds_terminate_all_requests( 6949230557Sjimharris SCIC_SDS_CONTROLLER_T * controller 6950230557Sjimharris) 6951230557Sjimharris{ 6952230557Sjimharris return scic_sds_terminate_reqests(controller, NULL, NULL); 6953230557Sjimharris} 6954230557Sjimharris 6955230557Sjimharris/** 6956230557Sjimharris * This method implements the actions taken by the SCIC_SDS_CONTROLLER on 6957230557Sjimharris * entry to the SCI_BASE_CONTROLLER_STATE_FAILED. 6958230557Sjimharris * - Set the state handlers to the controllers failed state. 6959230557Sjimharris * 6960230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 6961230557Sjimharris * SCIC_SDS_CONTROLLER object. 6962230557Sjimharris * 6963230557Sjimharris * @return none 6964230557Sjimharris */ 6965230557Sjimharrisstatic 6966230557Sjimharrisvoid scic_sds_controller_failed_state_enter( 6967230557Sjimharris SCI_BASE_OBJECT_T *object 6968230557Sjimharris) 6969230557Sjimharris{ 6970230557Sjimharris SCIC_SDS_CONTROLLER_T *this_controller; 6971230557Sjimharris this_controller= (SCIC_SDS_CONTROLLER_T *)object; 6972230557Sjimharris 6973230557Sjimharris scic_sds_controller_set_base_state_handlers( 6974230557Sjimharris this_controller, SCI_BASE_CONTROLLER_STATE_FAILED); 6975230557Sjimharris 6976230557Sjimharris if (this_controller->parent.error == SCI_CONTROLLER_FATAL_MEMORY_ERROR) 6977230557Sjimharris scic_sds_terminate_all_requests(this_controller); 6978230557Sjimharris else 6979230557Sjimharris scic_sds_controller_release_resource(this_controller); 6980230557Sjimharris 6981230557Sjimharris //notify framework the controller failed. 6982230557Sjimharris scic_cb_controller_error(this_controller, 6983230557Sjimharris this_controller->parent.error); 6984230557Sjimharris} 6985230557Sjimharris 6986230557Sjimharris// --------------------------------------------------------------------------- 6987230557Sjimharris 6988230557SjimharrisSCI_BASE_STATE_T 6989230557Sjimharris scic_sds_controller_state_table[SCI_BASE_CONTROLLER_MAX_STATES] = 6990230557Sjimharris{ 6991230557Sjimharris { 6992230557Sjimharris SCI_BASE_CONTROLLER_STATE_INITIAL, 6993230557Sjimharris scic_sds_controller_initial_state_enter, 6994230557Sjimharris NULL, 6995230557Sjimharris }, 6996230557Sjimharris { 6997230557Sjimharris SCI_BASE_CONTROLLER_STATE_RESET, 6998230557Sjimharris scic_sds_controller_reset_state_enter, 6999230557Sjimharris NULL, 7000230557Sjimharris }, 7001230557Sjimharris { 7002230557Sjimharris SCI_BASE_CONTROLLER_STATE_INITIALIZING, 7003230557Sjimharris scic_sds_controller_initializing_state_enter, 7004230557Sjimharris NULL, 7005230557Sjimharris }, 7006230557Sjimharris { 7007230557Sjimharris SCI_BASE_CONTROLLER_STATE_INITIALIZED, 7008230557Sjimharris scic_sds_controller_initialized_state_enter, 7009230557Sjimharris NULL, 7010230557Sjimharris }, 7011230557Sjimharris { 7012230557Sjimharris SCI_BASE_CONTROLLER_STATE_STARTING, 7013230557Sjimharris scic_sds_controller_starting_state_enter, 7014230557Sjimharris scic_sds_controller_starting_state_exit, 7015230557Sjimharris }, 7016230557Sjimharris { 7017230557Sjimharris SCI_BASE_CONTROLLER_STATE_READY, 7018230557Sjimharris scic_sds_controller_ready_state_enter, 7019230557Sjimharris scic_sds_controller_ready_state_exit, 7020230557Sjimharris }, 7021230557Sjimharris { 7022230557Sjimharris SCI_BASE_CONTROLLER_STATE_RESETTING, 7023230557Sjimharris scic_sds_controller_resetting_state_enter, 7024230557Sjimharris NULL, 7025230557Sjimharris }, 7026230557Sjimharris { 7027230557Sjimharris SCI_BASE_CONTROLLER_STATE_STOPPING, 7028230557Sjimharris scic_sds_controller_stopping_state_enter, 7029230557Sjimharris scic_sds_controller_stopping_state_exit, 7030230557Sjimharris }, 7031230557Sjimharris { 7032230557Sjimharris SCI_BASE_CONTROLLER_STATE_STOPPED, 7033230557Sjimharris scic_sds_controller_stopped_state_enter, 7034230557Sjimharris NULL, 7035230557Sjimharris }, 7036230557Sjimharris { 7037230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED, 7038230557Sjimharris scic_sds_controller_failed_state_enter, 7039230557Sjimharris NULL, 7040230557Sjimharris } 7041230557Sjimharris}; 7042230557Sjimharris 7043