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 SCIF_SAS_CONTROLLER 60230557Sjimharris * object. 61230557Sjimharris */ 62230557Sjimharris 63230557Sjimharris 64230557Sjimharris#include <dev/isci/scil/sci_status.h> 65230557Sjimharris#include <dev/isci/scil/sci_util.h> 66230557Sjimharris#include <dev/isci/scil/sci_controller.h> 67230557Sjimharris#include <dev/isci/scil/scic_controller.h> 68230557Sjimharris#include <dev/isci/scil/scic_user_callback.h> 69230557Sjimharris#include <dev/isci/scil/scif_user_callback.h> 70230557Sjimharris 71230557Sjimharris#include <dev/isci/scil/scif_sas_controller.h> 72230557Sjimharris#include <dev/isci/scil/scif_sas_library.h> 73230557Sjimharris#include <dev/isci/scil/scif_sas_logger.h> 74230557Sjimharris 75230557Sjimharris 76230557Sjimharris//****************************************************************************** 77230557Sjimharris//* P U B L I C M E T H O D S 78230557Sjimharris//****************************************************************************** 79230557Sjimharris 80230557SjimharrisSCI_STATUS scif_controller_construct( 81230557Sjimharris SCI_LIBRARY_HANDLE_T library, 82230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 83230557Sjimharris void * user_object 84230557Sjimharris) 85230557Sjimharris{ 86230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 87230557Sjimharris SCIF_SAS_LIBRARY_T * fw_library = (SCIF_SAS_LIBRARY_T*) library; 88230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 89230557Sjimharris 90231137Sjimharris // Validate the user supplied parameters. 91231137Sjimharris if ((library == SCI_INVALID_HANDLE) || (controller == SCI_INVALID_HANDLE)) 92231137Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 93231137Sjimharris 94230557Sjimharris SCIF_LOG_TRACE(( 95230557Sjimharris sci_base_object_get_logger(library), 96230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION, 97230557Sjimharris "scif_controller_construct(0x%x, 0x%x) enter\n", 98230557Sjimharris library, controller 99230557Sjimharris )); 100230557Sjimharris 101230557Sjimharris // Construct the base controller. As part of constructing the base 102230557Sjimharris // controller we ask it to also manage the MDL iteration for the Core. 103230557Sjimharris sci_base_controller_construct( 104230557Sjimharris &fw_controller->parent, 105230557Sjimharris sci_base_object_get_logger(fw_library), 106230557Sjimharris scif_sas_controller_state_table, 107230557Sjimharris fw_controller->mdes, 108230557Sjimharris SCIF_SAS_MAX_MEMORY_DESCRIPTORS, 109230557Sjimharris sci_controller_get_memory_descriptor_list_handle(fw_controller->core_object) 110230557Sjimharris ); 111230557Sjimharris 112230557Sjimharris scif_sas_controller_initialize_state_logging(fw_controller); 113230557Sjimharris 114230557Sjimharris sci_object_set_association(fw_controller, user_object); 115230557Sjimharris 116230557Sjimharris status = scic_controller_construct( 117230557Sjimharris fw_library->core_object, fw_controller->core_object, fw_controller 118230557Sjimharris ); 119230557Sjimharris 120230557Sjimharris // If the core controller was successfully constructed, then 121230557Sjimharris // finish construction of the framework controller. 122230557Sjimharris if (status == SCI_SUCCESS) 123230557Sjimharris { 124230557Sjimharris // Set the association in the core controller to this framework 125230557Sjimharris // controller. 126230557Sjimharris sci_object_set_association( 127230557Sjimharris (SCI_OBJECT_HANDLE_T) fw_controller->core_object, fw_controller 128230557Sjimharris ); 129230557Sjimharris 130230557Sjimharris sci_base_state_machine_change_state( 131230557Sjimharris &fw_controller->parent.state_machine, 132230557Sjimharris SCI_BASE_CONTROLLER_STATE_RESET 133230557Sjimharris ); 134230557Sjimharris } 135230557Sjimharris 136230557Sjimharris return status; 137230557Sjimharris} 138230557Sjimharris 139230557Sjimharris// --------------------------------------------------------------------------- 140230557Sjimharris 141230557SjimharrisSCI_STATUS scif_controller_initialize( 142230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 143230557Sjimharris) 144230557Sjimharris{ 145230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 146230557Sjimharris 147231137Sjimharris // Validate the user supplied parameters. 148231137Sjimharris if (controller == SCI_INVALID_HANDLE) 149231137Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 150231137Sjimharris 151230557Sjimharris SCIF_LOG_TRACE(( 152230557Sjimharris sci_base_object_get_logger(controller), 153230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION, 154230557Sjimharris "scif_controller_initialize(0x%x) enter\n", 155230557Sjimharris controller 156230557Sjimharris )); 157230557Sjimharris 158230557Sjimharris return fw_controller->state_handlers->initialize_handler( 159230557Sjimharris &fw_controller->parent 160230557Sjimharris ); 161230557Sjimharris} 162230557Sjimharris 163230557Sjimharris// --------------------------------------------------------------------------- 164230557Sjimharris 165230557SjimharrisU32 scif_controller_get_suggested_start_timeout( 166230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 167230557Sjimharris) 168230557Sjimharris{ 169230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 170230557Sjimharris 171230557Sjimharris // Validate the user supplied parameters. 172230557Sjimharris if (controller == SCI_INVALID_HANDLE) 173230557Sjimharris return 0; 174230557Sjimharris 175230557Sjimharris // Currently we aren't adding any additional time into the suggested 176230557Sjimharris // timeout value for the start operation. Simply utilize the core 177230557Sjimharris // value. 178230557Sjimharris return scic_controller_get_suggested_start_timeout(fw_controller->core_object); 179230557Sjimharris} 180230557Sjimharris 181230557Sjimharris// --------------------------------------------------------------------------- 182230557Sjimharris 183230557SjimharrisSCI_STATUS scif_controller_start( 184230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 185230557Sjimharris U32 timeout 186230557Sjimharris) 187230557Sjimharris{ 188230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 189230557Sjimharris 190231137Sjimharris // Validate the user supplied parameters. 191231137Sjimharris if (controller == SCI_INVALID_HANDLE) 192231137Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 193231137Sjimharris 194230557Sjimharris SCIF_LOG_TRACE(( 195230557Sjimharris sci_base_object_get_logger(controller), 196230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION, 197230557Sjimharris "scif_controller_start(0x%x, 0x%x) enter\n", 198230557Sjimharris controller, timeout 199230557Sjimharris )); 200230557Sjimharris 201230557Sjimharris return fw_controller->state_handlers-> 202230557Sjimharris start_handler(&fw_controller->parent, timeout); 203230557Sjimharris} 204230557Sjimharris 205230557Sjimharris// --------------------------------------------------------------------------- 206230557Sjimharris 207230557SjimharrisSCI_STATUS scif_controller_stop( 208230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 209230557Sjimharris U32 timeout 210230557Sjimharris) 211230557Sjimharris{ 212230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 213230557Sjimharris 214231137Sjimharris // Validate the user supplied parameters. 215231137Sjimharris if (controller == SCI_INVALID_HANDLE) 216231137Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 217231137Sjimharris 218230557Sjimharris SCIF_LOG_TRACE(( 219230557Sjimharris sci_base_object_get_logger(controller), 220230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN, 221230557Sjimharris "scif_controller_stop(0x%x, 0x%x) enter\n", 222230557Sjimharris controller, timeout 223230557Sjimharris )); 224230557Sjimharris 225230557Sjimharris return fw_controller->state_handlers-> 226230557Sjimharris stop_handler(&fw_controller->parent, timeout); 227230557Sjimharris 228230557Sjimharris} 229230557Sjimharris 230230557Sjimharris// --------------------------------------------------------------------------- 231230557Sjimharris 232230557SjimharrisSCI_STATUS scif_controller_reset( 233230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 234230557Sjimharris) 235230557Sjimharris{ 236230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 237230557Sjimharris 238231137Sjimharris // Validate the user supplied parameters. 239231137Sjimharris if (controller == SCI_INVALID_HANDLE) 240231137Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 241231137Sjimharris 242230557Sjimharris SCIF_LOG_TRACE(( 243230557Sjimharris sci_base_object_get_logger(controller), 244230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_CONTROLLER_RESET, 245230557Sjimharris "scif_controller_reset(0x%x) enter\n", 246230557Sjimharris controller 247230557Sjimharris )); 248230557Sjimharris 249230557Sjimharris return fw_controller->state_handlers-> 250230557Sjimharris reset_handler(&fw_controller->parent); 251230557Sjimharris} 252230557Sjimharris 253230557Sjimharris// --------------------------------------------------------------------------- 254230557Sjimharris 255230557SjimharrisSCI_CONTROLLER_HANDLE_T scif_controller_get_scic_handle( 256230557Sjimharris SCI_CONTROLLER_HANDLE_T controller 257230557Sjimharris) 258230557Sjimharris{ 259230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 260230557Sjimharris 261230557Sjimharris return fw_controller->core_object; 262230557Sjimharris} 263230557Sjimharris 264230557Sjimharris// --------------------------------------------------------------------------- 265230557Sjimharris 266230557SjimharrisSCI_IO_STATUS scif_controller_start_io( 267230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 268230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 269230557Sjimharris SCI_IO_REQUEST_HANDLE_T io_request, 270230557Sjimharris U16 io_tag 271230557Sjimharris) 272230557Sjimharris{ 273230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 274231296Sjimharris SCI_STATUS status; 275230557Sjimharris 276230557Sjimharris SCIF_LOG_TRACE(( 277230557Sjimharris sci_base_object_get_logger(controller), 278230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 279230557Sjimharris "scif_controller_start_io(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 280230557Sjimharris controller, remote_device, io_request, io_tag 281230557Sjimharris )); 282230557Sjimharris 283230557Sjimharris if ( 284230557Sjimharris sci_pool_empty(fw_controller->hprq.pool) 285230557Sjimharris || scif_sas_controller_sufficient_resource(controller) 286230557Sjimharris ) 287230557Sjimharris { 288231296Sjimharris status = fw_controller->state_handlers->start_io_handler( 289230557Sjimharris (SCI_BASE_CONTROLLER_T*) controller, 290230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T*) remote_device, 291230557Sjimharris (SCI_BASE_REQUEST_T*) io_request, 292230557Sjimharris io_tag 293230557Sjimharris ); 294230557Sjimharris } 295230557Sjimharris else 296231296Sjimharris status = SCI_FAILURE_INSUFFICIENT_RESOURCES; 297231296Sjimharris 298231296Sjimharris return (SCI_IO_STATUS)status; 299230557Sjimharris} 300230557Sjimharris 301230557Sjimharris// --------------------------------------------------------------------------- 302230557Sjimharris 303230557SjimharrisSCI_TASK_STATUS scif_controller_start_task( 304230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 305230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 306230557Sjimharris SCI_TASK_REQUEST_HANDLE_T task_request, 307230557Sjimharris U16 io_tag 308230557Sjimharris) 309230557Sjimharris{ 310230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 311231296Sjimharris SCI_STATUS status; 312230557Sjimharris 313230557Sjimharris // Validate the user supplied parameters. 314230557Sjimharris if ( (controller == SCI_INVALID_HANDLE) 315230557Sjimharris || (remote_device == SCI_INVALID_HANDLE) 316230557Sjimharris || (task_request == SCI_INVALID_HANDLE) ) 317230557Sjimharris { 318231296Sjimharris return SCI_TASK_FAILURE_INVALID_PARAMETER_VALUE; 319230557Sjimharris } 320230557Sjimharris 321231137Sjimharris SCIF_LOG_TRACE(( 322231137Sjimharris sci_base_object_get_logger(controller), 323231137Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 324231137Sjimharris "scif_controller_start_task(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 325231137Sjimharris controller, remote_device, task_request, io_tag 326231137Sjimharris )); 327231137Sjimharris 328230557Sjimharris if (scif_sas_controller_sufficient_resource(controller)) 329230557Sjimharris { 330231296Sjimharris status = fw_controller->state_handlers->start_task_handler( 331230557Sjimharris (SCI_BASE_CONTROLLER_T*) controller, 332230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T*) remote_device, 333230557Sjimharris (SCI_BASE_REQUEST_T*) task_request, 334230557Sjimharris io_tag 335230557Sjimharris ); 336230557Sjimharris } 337230557Sjimharris else 338231296Sjimharris status = SCI_FAILURE_INSUFFICIENT_RESOURCES; 339231296Sjimharris 340231296Sjimharris return (SCI_TASK_STATUS)status; 341230557Sjimharris} 342230557Sjimharris 343230557Sjimharris// --------------------------------------------------------------------------- 344230557Sjimharris 345230557SjimharrisSCI_STATUS scif_controller_complete_io( 346230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 347230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 348230557Sjimharris SCI_IO_REQUEST_HANDLE_T io_request 349230557Sjimharris) 350230557Sjimharris{ 351230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 352230557Sjimharris 353230557Sjimharris SCIF_LOG_TRACE(( 354230557Sjimharris sci_base_object_get_logger(controller), 355230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 356230557Sjimharris "scif_controller_complete_io(0x%x, 0x%x, 0x%x) enter\n", 357230557Sjimharris controller, remote_device, io_request 358230557Sjimharris )); 359230557Sjimharris 360230557Sjimharris return fw_controller->state_handlers->complete_io_handler( 361230557Sjimharris (SCI_BASE_CONTROLLER_T*) controller, 362230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T*) remote_device, 363230557Sjimharris (SCI_BASE_REQUEST_T*) io_request 364230557Sjimharris ); 365230557Sjimharris} 366230557Sjimharris 367230557Sjimharris// --------------------------------------------------------------------------- 368230557Sjimharris 369230557SjimharrisSCI_STATUS scif_controller_complete_task( 370230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 371230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 372230557Sjimharris SCI_TASK_REQUEST_HANDLE_T task_request 373230557Sjimharris) 374230557Sjimharris{ 375230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 376230557Sjimharris 377230557Sjimharris // Validate the user supplied parameters. 378230557Sjimharris if ( (controller == SCI_INVALID_HANDLE) 379230557Sjimharris || (remote_device == SCI_INVALID_HANDLE) 380230557Sjimharris || (task_request == SCI_INVALID_HANDLE) ) 381230557Sjimharris { 382230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 383230557Sjimharris } 384230557Sjimharris 385231137Sjimharris SCIF_LOG_TRACE(( 386231137Sjimharris sci_base_object_get_logger(controller), 387231137Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_TASK_MANAGEMENT, 388231137Sjimharris "scif_controller_complete_task(0x%x, 0x%x, 0x%x) enter\n", 389231137Sjimharris controller, remote_device, task_request 390231137Sjimharris )); 391231137Sjimharris 392230557Sjimharris return fw_controller->state_handlers->complete_task_handler( 393230557Sjimharris (SCI_BASE_CONTROLLER_T*) controller, 394230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T*) remote_device, 395230557Sjimharris (SCI_BASE_REQUEST_T*) task_request 396230557Sjimharris ); 397230557Sjimharris} 398230557Sjimharris 399230557Sjimharris// --------------------------------------------------------------------------- 400230557Sjimharris 401230557SjimharrisSCI_STATUS scif_controller_get_domain_handle( 402230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 403230557Sjimharris U8 port_index, 404230557Sjimharris SCI_DOMAIN_HANDLE_T * domain_handle 405230557Sjimharris) 406230557Sjimharris{ 407230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 408230557Sjimharris 409230557Sjimharris // Validate the user supplied parameters. 410230557Sjimharris if (controller == SCI_INVALID_HANDLE) 411230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 412230557Sjimharris 413230557Sjimharris // Retrieve the domain handle if the supplied index is legitimate. 414230557Sjimharris if (port_index < SCI_MAX_PORTS) 415230557Sjimharris { 416230557Sjimharris *domain_handle = &fw_controller->domains[port_index]; 417230557Sjimharris return SCI_SUCCESS; 418230557Sjimharris } 419230557Sjimharris 420230557Sjimharris return SCI_FAILURE_INVALID_PORT; 421230557Sjimharris} 422230557Sjimharris 423230557Sjimharris/** 424230557Sjimharris * @brief This method builds the memory descriptor list for this 425230557Sjimharris * controller. 426230557Sjimharris * 427230557Sjimharris * @param[in] fw_controller This parameter specifies the framework 428230557Sjimharris * controller object for which to build the MDL. 429230557Sjimharris * 430230557Sjimharris * @return none 431230557Sjimharris */ 432230557Sjimharrisvoid scif_sas_controller_build_mdl( 433230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 434230557Sjimharris) 435230557Sjimharris{ 436230557Sjimharris // one internal request for each domain. 437230557Sjimharris sci_base_mde_construct( 438230557Sjimharris &fw_controller->mdes[SCIF_SAS_MDE_INTERNAL_IO], 439230557Sjimharris 4, 440230557Sjimharris fw_controller->internal_request_entries * 441230557Sjimharris scif_sas_internal_request_get_object_size(), 442230557Sjimharris SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS 443230557Sjimharris ); 444230557Sjimharris} 445230557Sjimharris 446230557Sjimharris// --------------------------------------------------------------------------- 447230557Sjimharris 448230557SjimharrisSCI_STATUS scif_controller_set_mode( 449230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 450230557Sjimharris SCI_CONTROLLER_MODE mode 451230557Sjimharris) 452230557Sjimharris{ 453230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 454230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 455230557Sjimharris 456230557Sjimharris if ( 457230557Sjimharris (fw_controller->parent.state_machine.current_state_id 458230557Sjimharris == SCI_BASE_CONTROLLER_STATE_INITIALIZING) 459230557Sjimharris || (fw_controller->parent.state_machine.current_state_id 460230557Sjimharris == SCI_BASE_CONTROLLER_STATE_INITIALIZED) 461230557Sjimharris ) 462230557Sjimharris { 463230557Sjimharris switch (mode) 464230557Sjimharris { 465230557Sjimharris case SCI_MODE_SPEED: 466230557Sjimharris fw_controller->internal_request_entries = 467230557Sjimharris MIN(fw_controller->internal_request_entries, SCIF_SAS_MAX_INTERNAL_REQUEST_COUNT); 468230557Sjimharris scif_sas_controller_build_mdl(fw_controller); 469230557Sjimharris break; 470230557Sjimharris 471230557Sjimharris case SCI_MODE_SIZE: 472230557Sjimharris fw_controller->internal_request_entries = 473230557Sjimharris MIN(fw_controller->internal_request_entries, SCIF_SAS_MIN_INTERNAL_REQUEST_COUNT); 474230557Sjimharris scif_sas_controller_build_mdl(fw_controller); 475230557Sjimharris break; 476230557Sjimharris 477230557Sjimharris default: 478230557Sjimharris status = SCI_FAILURE_INVALID_PARAMETER_VALUE; 479230557Sjimharris break; 480230557Sjimharris } 481230557Sjimharris } 482230557Sjimharris else 483230557Sjimharris status = SCI_FAILURE_INVALID_STATE; 484230557Sjimharris 485230557Sjimharris if (status != SCI_SUCCESS) 486230557Sjimharris { 487230557Sjimharris return status; 488230557Sjimharris } 489230557Sjimharris else 490230557Sjimharris { 491230557Sjimharris // Currently, the framework doesn't change any configurations for 492230557Sjimharris // speed or size modes. Default to speed mode basically. 493230557Sjimharris return scic_controller_set_mode(fw_controller->core_object, mode); 494230557Sjimharris } 495230557Sjimharris} 496230557Sjimharris 497230557Sjimharris// --------------------------------------------------------------------------- 498230557Sjimharris 499230557SjimharrisU32 scif_controller_get_sat_compliance_version( 500230557Sjimharris void 501230557Sjimharris) 502230557Sjimharris{ 503230557Sjimharris /// @todo Fix return of SAT compliance version. 504230557Sjimharris return 0; 505230557Sjimharris} 506230557Sjimharris 507230557Sjimharris// --------------------------------------------------------------------------- 508230557Sjimharris 509230557SjimharrisU32 scif_controller_get_sat_compliance_version_revision( 510230557Sjimharris void 511230557Sjimharris) 512230557Sjimharris{ 513230557Sjimharris /// @todo Fix return of SAT compliance revision. 514230557Sjimharris return 0; 515230557Sjimharris} 516230557Sjimharris 517230557Sjimharris// --------------------------------------------------------------------------- 518230557Sjimharris 519230557SjimharrisSCI_STATUS scif_user_parameters_set( 520230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 521230557Sjimharris SCIF_USER_PARAMETERS_T * scif_parms 522230557Sjimharris) 523230557Sjimharris{ 524230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 525230557Sjimharris 526230557Sjimharris //validate all the registry entries before overwriting the default parameter 527230557Sjimharris //values. 528230557Sjimharris if (scif_parms->sas.is_sata_ncq_enabled != 1 && scif_parms->sas.is_sata_ncq_enabled != 0) 529230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 530230557Sjimharris 531230557Sjimharris if (scif_parms->sas.max_ncq_depth < 1 && scif_parms->sas.max_ncq_depth > 32) 532230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 533230557Sjimharris 534230557Sjimharris if (scif_parms->sas.is_sata_standby_timer_enabled != 1 535230557Sjimharris && scif_parms->sas.is_sata_standby_timer_enabled != 0) 536230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 537230557Sjimharris 538230557Sjimharris if (scif_parms->sas.is_non_zero_buffer_offsets_enabled != 1 539230557Sjimharris && scif_parms->sas.is_non_zero_buffer_offsets_enabled != 0) 540230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 541230557Sjimharris 542230557Sjimharris if (scif_parms->sas.reset_type != SCI_SAS_ABORT_TASK 543230557Sjimharris && scif_parms->sas.reset_type != SCI_SAS_ABORT_TASK_SET 544230557Sjimharris && scif_parms->sas.reset_type != SCI_SAS_CLEAR_TASK_SET 545230557Sjimharris && scif_parms->sas.reset_type != SCI_SAS_LOGICAL_UNIT_RESET 546230557Sjimharris && scif_parms->sas.reset_type != SCI_SAS_I_T_NEXUS_RESET 547230557Sjimharris && scif_parms->sas.reset_type != SCI_SAS_CLEAR_ACA 548230557Sjimharris && scif_parms->sas.reset_type != SCI_SAS_QUERY_TASK 549230557Sjimharris && scif_parms->sas.reset_type != SCI_SAS_QUERY_TASK_SET 550230557Sjimharris && scif_parms->sas.reset_type != SCI_SAS_QUERY_ASYNCHRONOUS_EVENT 551230557Sjimharris && scif_parms->sas.reset_type != SCI_SAS_HARD_RESET) 552230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 553230557Sjimharris 554230557Sjimharris if (scif_parms->sas.clear_affiliation_during_controller_stop != 1 555230557Sjimharris && scif_parms->sas.clear_affiliation_during_controller_stop !=0) 556230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 557230557Sjimharris 558230557Sjimharris memcpy((&fw_controller->user_parameters), scif_parms, sizeof(*scif_parms)); 559230557Sjimharris 560230557Sjimharris // In the future more could be done to prevent setting parameters at the 561230557Sjimharris // wrong time, but for now we'll simply set the values even if it is too 562230557Sjimharris // late for them to take affect. 563230557Sjimharris return SCI_SUCCESS; 564230557Sjimharris} 565230557Sjimharris 566230557Sjimharris// --------------------------------------------------------------------------- 567230557Sjimharris 568230557Sjimharris#if !defined(DISABLE_INTERRUPTS) 569230557Sjimharris 570230557Sjimharris/** 571230557Sjimharris * @brief This routine check each domain of the controller to see if 572230557Sjimharris * any domain is overriding interrupt coalescence. 573230557Sjimharris * 574230557Sjimharris * @param[in] fw_controller frame controller 575230557Sjimharris * @param[in] fw_smp_phy The smp phy to be freed. 576230557Sjimharris * 577230557Sjimharris * @return none 578230557Sjimharris */ 579230557Sjimharrisstatic 580230557SjimharrisBOOL scif_sas_controller_is_overriding_interrupt_coalescence( 581230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 582230557Sjimharris) 583230557Sjimharris{ 584230557Sjimharris U8 index; 585230557Sjimharris 586230557Sjimharris for(index = 0; index < SCI_MAX_DOMAINS; index++) 587230557Sjimharris { 588230557Sjimharris if(fw_controller->domains[index].parent.state_machine.current_state_id == 589230557Sjimharris SCI_BASE_DOMAIN_STATE_DISCOVERING) 590230557Sjimharris return TRUE; 591230557Sjimharris } 592230557Sjimharris 593230557Sjimharris return FALSE; 594230557Sjimharris} 595230557Sjimharris 596230557SjimharrisSCI_STATUS scif_controller_set_interrupt_coalescence( 597230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 598230557Sjimharris U32 coalesce_number, 599230557Sjimharris U32 coalesce_timeout 600230557Sjimharris) 601230557Sjimharris{ 602230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T * )controller; 603230557Sjimharris 604230557Sjimharris ///when framework is in the middle of temporarily overriding the interrupt 605230557Sjimharris ///coalescence values, user's request of setting interrupt coalescence 606230557Sjimharris ///will be saved. As soon as the framework done the temporary overriding, 607230557Sjimharris ///it will serve user's request to set new interrupt coalescence. 608230557Sjimharris if (scif_sas_controller_is_overriding_interrupt_coalescence(fw_controller)) 609230557Sjimharris { 610230557Sjimharris U32 curr_coalesce_number; 611230557Sjimharris U32 curr_coalesce_timeout; 612230557Sjimharris SCI_STATUS core_status; 613230557Sjimharris 614230557Sjimharris // save current interrupt coalescence info. 615230557Sjimharris scic_controller_get_interrupt_coalescence ( 616230557Sjimharris fw_controller->core_object, &curr_coalesce_number, &curr_coalesce_timeout); 617230557Sjimharris 618230557Sjimharris //try user's request out in the core, but immediately restore core's 619230557Sjimharris //current setting. 620230557Sjimharris core_status = scic_controller_set_interrupt_coalescence( 621230557Sjimharris fw_controller->core_object, coalesce_number, coalesce_timeout); 622230557Sjimharris 623230557Sjimharris if ( core_status == SCI_SUCCESS ) 624230557Sjimharris { 625230557Sjimharris fw_controller->saved_interrupt_coalesce_number = (U16)coalesce_number; 626230557Sjimharris fw_controller->saved_interrupt_coalesce_timeout = coalesce_timeout; 627230557Sjimharris } 628230557Sjimharris 629230557Sjimharris //restore current interrupt coalescence. 630230557Sjimharris scic_controller_set_interrupt_coalescence( 631230557Sjimharris fw_controller->core_object, curr_coalesce_number, curr_coalesce_timeout); 632230557Sjimharris 633230557Sjimharris return core_status; 634230557Sjimharris } 635230557Sjimharris else 636230557Sjimharris { 637230557Sjimharris ///If framework is not internally overriding the interrupt coalescence, 638230557Sjimharris ///serve user's request immediately by passing the reqeust to core. 639230557Sjimharris return scic_controller_set_interrupt_coalescence( 640230557Sjimharris fw_controller->core_object, coalesce_number, coalesce_timeout); 641230557Sjimharris } 642230557Sjimharris} 643230557Sjimharris 644230557Sjimharris// --------------------------------------------------------------------------- 645230557Sjimharris 646230557Sjimharrisvoid scif_controller_get_interrupt_coalescence( 647230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 648230557Sjimharris U32 * coalesce_number, 649230557Sjimharris U32 * coalesce_timeout 650230557Sjimharris) 651230557Sjimharris{ 652230557Sjimharris SCIF_SAS_CONTROLLER_T * scif_controller = (SCIF_SAS_CONTROLLER_T * )controller; 653230557Sjimharris 654230557Sjimharris scic_controller_get_interrupt_coalescence( 655230557Sjimharris scif_controller->core_object, coalesce_number, coalesce_timeout); 656230557Sjimharris} 657230557Sjimharris 658230557Sjimharris/** 659230557Sjimharris * @brief This method will save the interrupt coalescence values. If 660230557Sjimharris * the interrupt coalescence values have already been saved, 661230557Sjimharris * then this method performs no operations. 662230557Sjimharris * 663230557Sjimharris * @param[in,out] fw_controller This parameter specifies the controller 664230557Sjimharris * for which to save the interrupt coalescence values. 665230557Sjimharris * 666230557Sjimharris * @return none 667230557Sjimharris */ 668230557Sjimharrisvoid scif_sas_controller_save_interrupt_coalescence( 669230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 670230557Sjimharris) 671230557Sjimharris{ 672230557Sjimharris if ( !scif_sas_controller_is_overriding_interrupt_coalescence(fw_controller)) 673230557Sjimharris { 674230557Sjimharris // Override core's interrupt coalescing settings during SMP 675230557Sjimharris // DISCOVER process cause' there is only 1 outstanding SMP 676230557Sjimharris // request per domain is allowed. 677230557Sjimharris scic_controller_get_interrupt_coalescence( 678230557Sjimharris fw_controller->core_object, 679230557Sjimharris (U32*)&(fw_controller->saved_interrupt_coalesce_number), 680230557Sjimharris &(fw_controller->saved_interrupt_coalesce_timeout) 681230557Sjimharris ); 682230557Sjimharris 683230557Sjimharris // Temporarily disable the interrupt coalescing. 684230557Sjimharris scic_controller_set_interrupt_coalescence(fw_controller->core_object,0,0); 685230557Sjimharris } 686230557Sjimharris} 687230557Sjimharris 688230557Sjimharris/** 689230557Sjimharris * @brief This method will restore the interrupt coalescence values. If 690230557Sjimharris * the interrupt coalescence values have not already been saved, 691230557Sjimharris * then this method performs no operations. 692230557Sjimharris * 693230557Sjimharris * @param[in,out] fw_controller This parameter specifies the controller 694230557Sjimharris * for which to restore the interrupt coalescence values. 695230557Sjimharris * 696230557Sjimharris * @return none 697230557Sjimharris */ 698230557Sjimharrisvoid scif_sas_controller_restore_interrupt_coalescence( 699230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 700230557Sjimharris) 701230557Sjimharris{ 702230557Sjimharris if ( !scif_sas_controller_is_overriding_interrupt_coalescence(fw_controller)) 703230557Sjimharris scic_controller_set_interrupt_coalescence( 704230557Sjimharris fw_controller->core_object, 705230557Sjimharris fw_controller->saved_interrupt_coalesce_number, 706230557Sjimharris fw_controller->saved_interrupt_coalesce_timeout 707230557Sjimharris ); 708230557Sjimharris} 709230557Sjimharris 710230557Sjimharris#endif // !defined(DISABLE_INTERRUPTS) 711230557Sjimharris 712230557Sjimharris// --------------------------------------------------------------------------- 713230557Sjimharris 714230557Sjimharrisvoid scic_cb_controller_start_complete( 715230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 716230557Sjimharris SCI_STATUS completion_status 717230557Sjimharris) 718230557Sjimharris{ 719230557Sjimharris SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*) 720230557Sjimharris sci_object_get_association(controller); 721230557Sjimharris 722230557Sjimharris SCIF_LOG_TRACE(( 723230557Sjimharris sci_base_object_get_logger(controller), 724230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION, 725230557Sjimharris "scic_cb_controller_start_complete(0x%x, 0x%x) enter\n", 726230557Sjimharris controller, completion_status 727230557Sjimharris )); 728230557Sjimharris 729230557Sjimharris if (completion_status == SCI_SUCCESS 730230557Sjimharris || completion_status == SCI_FAILURE_TIMEOUT) 731230557Sjimharris { 732230557Sjimharris // Even the initialization of the core controller timed out, framework 733230557Sjimharris // controller should still transit to READY state. 734230557Sjimharris sci_base_state_machine_change_state( 735230557Sjimharris &fw_controller->parent.state_machine, 736230557Sjimharris SCI_BASE_CONTROLLER_STATE_READY 737230557Sjimharris ); 738230557Sjimharris } 739230557Sjimharris 740230557Sjimharris scif_cb_controller_start_complete(fw_controller, completion_status); 741230557Sjimharris} 742230557Sjimharris 743230557Sjimharris// --------------------------------------------------------------------------- 744230557Sjimharris 745230557Sjimharrisvoid scic_cb_controller_stop_complete( 746230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 747230557Sjimharris SCI_STATUS completion_status 748230557Sjimharris) 749230557Sjimharris{ 750230557Sjimharris SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*) 751230557Sjimharris sci_object_get_association(controller); 752230557Sjimharris 753230557Sjimharris SCIF_LOG_TRACE(( 754230557Sjimharris sci_base_object_get_logger(controller), 755230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN, 756230557Sjimharris "scic_cb_controller_stop_complete(0x%x, 0x%x) enter\n", 757230557Sjimharris controller, completion_status 758230557Sjimharris )); 759230557Sjimharris 760230557Sjimharris if (completion_status == SCI_SUCCESS) 761230557Sjimharris { 762230557Sjimharris sci_base_state_machine_change_state( 763230557Sjimharris &fw_controller->parent.state_machine, 764230557Sjimharris SCI_BASE_CONTROLLER_STATE_STOPPED 765230557Sjimharris ); 766230557Sjimharris } 767230557Sjimharris else 768230557Sjimharris { 769230557Sjimharris sci_base_state_machine_change_state( 770230557Sjimharris &fw_controller->parent.state_machine, 771230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED 772230557Sjimharris ); 773230557Sjimharris } 774230557Sjimharris 775230557Sjimharris scif_cb_controller_stop_complete(fw_controller, completion_status); 776230557Sjimharris} 777230557Sjimharris 778230557Sjimharris 779230557Sjimharris// --------------------------------------------------------------------------- 780230557Sjimharris 781230557Sjimharrisvoid scic_cb_controller_error( 782230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 783230557Sjimharris SCI_CONTROLLER_ERROR error 784230557Sjimharris) 785230557Sjimharris{ 786230557Sjimharris SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*) 787230557Sjimharris sci_object_get_association(controller); 788230557Sjimharris 789230557Sjimharris fw_controller->parent.error = error; 790230557Sjimharris 791230557Sjimharris SCIF_LOG_TRACE(( 792230557Sjimharris sci_base_object_get_logger(controller), 793230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN, 794230557Sjimharris "scic_cb_controller_not_ready(0x%x) enter\n", 795230557Sjimharris controller 796230557Sjimharris )); 797230557Sjimharris 798230557Sjimharris sci_base_state_machine_change_state( 799230557Sjimharris &fw_controller->parent.state_machine, 800230557Sjimharris SCI_BASE_CONTROLLER_STATE_FAILED 801230557Sjimharris ); 802230557Sjimharris} 803230557Sjimharris 804230557Sjimharris//****************************************************************************** 805230557Sjimharris//* P R O T E C T E D M E T H O D S 806230557Sjimharris//****************************************************************************** 807230557Sjimharris 808230557Sjimharris/** 809230557Sjimharris * @brief This method is utilized to continue an internal IO operation 810230557Sjimharris * on the controller. This method is utilized for SAT translated 811230557Sjimharris * requests that generate multiple ATA commands in order to fulfill 812230557Sjimharris * the original SCSI request. 813230557Sjimharris * 814230557Sjimharris * @param[in] controller This parameter specifies the controller on which 815230557Sjimharris * to continue an internal IO request. 816230557Sjimharris * @param[in] remote_device This parameter specifies the remote device 817230557Sjimharris * on which to continue an internal IO request. 818230557Sjimharris * @param[in] io_request This parameter specifies the IO request to be 819230557Sjimharris * continue. 820230557Sjimharris * 821230557Sjimharris * @return Indicate if the continue operation was successful. 822230557Sjimharris * @retval SCI_SUCCESS This value is returned if the operation succeeded. 823230557Sjimharris */ 824230557SjimharrisSCI_STATUS scif_sas_controller_continue_io( 825230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 826230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 827230557Sjimharris SCI_IO_REQUEST_HANDLE_T io_request 828230557Sjimharris) 829230557Sjimharris{ 830230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller; 831230557Sjimharris 832230557Sjimharris return fw_controller->state_handlers->continue_io_handler( 833230557Sjimharris (SCI_BASE_CONTROLLER_T*) controller, 834230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T*) remote_device, 835230557Sjimharris (SCI_BASE_REQUEST_T*) io_request 836230557Sjimharris ); 837230557Sjimharris} 838230557Sjimharris 839230557Sjimharris/** 840230557Sjimharris * @brief This method will attempt to destruct a framework controller. 841230557Sjimharris * This includes free any resources retreived from the user (e.g. 842230557Sjimharris * timers). 843230557Sjimharris * 844230557Sjimharris * @param[in] fw_controller This parameter specifies the framework 845230557Sjimharris * controller to destructed. 846230557Sjimharris * 847230557Sjimharris * @return none 848230557Sjimharris */ 849230557Sjimharrisvoid scif_sas_controller_destruct( 850230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 851230557Sjimharris) 852230557Sjimharris{ 853230557Sjimharris SCIF_LOG_TRACE(( 854230557Sjimharris sci_base_object_get_logger(fw_controller), 855230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN, 856230557Sjimharris "scif_sas_controller_destruct(0x%x) enter\n", 857230557Sjimharris fw_controller 858230557Sjimharris )); 859230557Sjimharris} 860230557Sjimharris 861230557Sjimharris//----------------------------------------------------------------------------- 862230557Sjimharris// INTERNAL REQUEST RELATED METHODS 863230557Sjimharris//----------------------------------------------------------------------------- 864230557Sjimharris 865230557Sjimharris/** 866230557Sjimharris * @brief This routine is to allocate the memory for creating a new internal 867230557Sjimharris * request. 868230557Sjimharris * 869230557Sjimharris * @param[in] scif_controller handle to frame controller 870230557Sjimharris * 871230557Sjimharris * @return void* address to internal request memory 872230557Sjimharris */ 873230557Sjimharrisvoid * scif_sas_controller_allocate_internal_request( 874230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 875230557Sjimharris) 876230557Sjimharris{ 877230557Sjimharris POINTER_UINT internal_io_address; 878230557Sjimharris 879230557Sjimharris if( !sci_pool_empty(fw_controller->internal_request_memory_pool) ) 880230557Sjimharris { 881230557Sjimharris sci_pool_get( 882230557Sjimharris fw_controller->internal_request_memory_pool, internal_io_address 883230557Sjimharris ); 884230557Sjimharris 885230557Sjimharris //clean the memory. 886230557Sjimharris memset((char*)internal_io_address, 0, scif_sas_internal_request_get_object_size()); 887230557Sjimharris 888230557Sjimharris return (void *) internal_io_address; 889230557Sjimharris } 890230557Sjimharris else 891230557Sjimharris return NULL; 892230557Sjimharris} 893230557Sjimharris 894230557Sjimharris/** 895230557Sjimharris * @brief This routine is to free the memory for a completed internal request. 896230557Sjimharris * 897230557Sjimharris * @param[in] scif_controller handle to frame controller 898230557Sjimharris * @param[in] fw_internal_io The internal IO to be freed. 899230557Sjimharris * 900230557Sjimharris * @return none 901230557Sjimharris */ 902230557Sjimharrisvoid scif_sas_controller_free_internal_request( 903230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 904230557Sjimharris void * fw_internal_request_buffer 905230557Sjimharris) 906230557Sjimharris{ 907230557Sjimharris SCIF_LOG_TRACE(( 908230557Sjimharris sci_base_object_get_logger(fw_controller), 909230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 910230557Sjimharris "scif_controller_free_internal_request(0x%x, 0x%x) enter\n", 911230557Sjimharris fw_controller, fw_internal_request_buffer 912230557Sjimharris )); 913230557Sjimharris 914230557Sjimharris //return the memory to to pool. 915230557Sjimharris if( !sci_pool_full(fw_controller->internal_request_memory_pool) ) 916230557Sjimharris { 917230557Sjimharris sci_pool_put( 918230557Sjimharris fw_controller->internal_request_memory_pool, 919230557Sjimharris (POINTER_UINT) fw_internal_request_buffer 920230557Sjimharris ); 921230557Sjimharris } 922230557Sjimharris} 923230557Sjimharris 924230557Sjimharris 925230557Sjimharris/** 926230557Sjimharris * @brief this routine is called by OS' DPC to start io requests from internal 927230557Sjimharris * high priority request queue 928230557Sjimharris * @param[in] fw_controller The framework controller. 929230557Sjimharris * 930230557Sjimharris * @return none 931230557Sjimharris */ 932230557Sjimharrisvoid scif_sas_controller_start_high_priority_io( 933230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 934230557Sjimharris) 935230557Sjimharris{ 936230557Sjimharris POINTER_UINT io_address; 937230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io; 938230557Sjimharris SCI_STATUS status; 939230557Sjimharris 940230557Sjimharris SCIF_LOG_TRACE(( 941230557Sjimharris sci_base_object_get_logger(fw_controller), 942230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 943230557Sjimharris "scif_controller_start_high_priority_io(0x%x) enter\n", 944230557Sjimharris fw_controller 945230557Sjimharris )); 946230557Sjimharris 947230557Sjimharris while ( !sci_pool_empty(fw_controller->hprq.pool) ) 948230557Sjimharris { 949230557Sjimharris sci_pool_get(fw_controller->hprq.pool, io_address); 950230557Sjimharris 951230557Sjimharris fw_io = (SCIF_SAS_IO_REQUEST_T *)io_address; 952230557Sjimharris 953230557Sjimharris status = fw_controller->state_handlers->start_high_priority_io_handler( 954230557Sjimharris (SCI_BASE_CONTROLLER_T*) fw_controller, 955230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T*) fw_io->parent.device, 956230557Sjimharris (SCI_BASE_REQUEST_T*) fw_io, 957230557Sjimharris SCI_CONTROLLER_INVALID_IO_TAG 958230557Sjimharris ); 959230557Sjimharris } 960230557Sjimharris} 961230557Sjimharris 962230557Sjimharris/** 963230557Sjimharris * @brief This method will check how many outstanding IOs currently and number 964230557Sjimharris * of IOs in high priority queue, if the overall number exceeds the max_tc, 965230557Sjimharris * return FALSE. 966230557Sjimharris * 967230557Sjimharris * @param[in] fw_controller The framework controller. 968230557Sjimharris * 969230557Sjimharris * @return BOOL Indicate whether there is sufficient resource to start an IO. 970230557Sjimharris * @retvalue TRUE The controller has sufficient resource. 971230557Sjimharris * @retvalue FALSE There is not sufficient resource available. 972230557Sjimharris */ 973230557SjimharrisBOOL scif_sas_controller_sufficient_resource( 974230557Sjimharris SCIF_SAS_CONTROLLER_T *fw_controller 975230557Sjimharris) 976230557Sjimharris{ 977230557Sjimharris SCIF_SAS_DOMAIN_T * fw_domain; 978230557Sjimharris U32 domain_index; 979230557Sjimharris U32 outstanding_io_count = 0; 980230557Sjimharris U32 high_priority_io_count = 0; 981230557Sjimharris 982230557Sjimharris for(domain_index = 0; domain_index < SCI_MAX_DOMAINS; domain_index++) 983230557Sjimharris { 984230557Sjimharris fw_domain = &fw_controller->domains[domain_index]; 985230557Sjimharris outstanding_io_count += fw_domain->request_list.element_count; 986230557Sjimharris } 987230557Sjimharris 988230557Sjimharris high_priority_io_count = sci_pool_count(fw_controller->hprq.pool); 989230557Sjimharris 990230557Sjimharris if ( (outstanding_io_count + high_priority_io_count) > SCI_MAX_IO_REQUESTS ) 991230557Sjimharris return FALSE; 992230557Sjimharris 993230557Sjimharris return TRUE; 994230557Sjimharris} 995230557Sjimharris 996230557Sjimharris 997230557Sjimharris/** 998230557Sjimharris * @brief This method is the starting point to complete high prority io for a 999230557Sjimharris * controller then down to domain, device. 1000230557Sjimharris * 1001230557Sjimharris * @param[in] fw_controller The framework controller 1002230557Sjimharris * @param[in] remote_device The framework remote device. 1003230557Sjimharris * @param[in] io_request The high priority io request to be completed. 1004230557Sjimharris * 1005230557Sjimharris * @return SCI_STATUS indicate the completion status from framework down to the 1006230557Sjimharris * core. 1007230557Sjimharris */ 1008230557SjimharrisSCI_STATUS scif_sas_controller_complete_high_priority_io( 1009230557Sjimharris SCIF_SAS_CONTROLLER_T *fw_controller, 1010230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T *remote_device, 1011230557Sjimharris SCIF_SAS_REQUEST_T *io_request 1012230557Sjimharris) 1013230557Sjimharris{ 1014230557Sjimharris SCIF_LOG_TRACE(( 1015230557Sjimharris sci_base_object_get_logger(fw_controller), 1016230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST, 1017230557Sjimharris "scif_sas_controller_complete_high_priority_io(0x%x, 0x%x, 0x%x) enter\n", 1018230557Sjimharris fw_controller, remote_device, io_request 1019230557Sjimharris )); 1020230557Sjimharris 1021230557Sjimharris //call controller's new added complete_high_priority_io_handler 1022230557Sjimharris return fw_controller->state_handlers->complete_high_priority_io_handler( 1023230557Sjimharris (SCI_BASE_CONTROLLER_T*) fw_controller, 1024230557Sjimharris (SCI_BASE_REMOTE_DEVICE_T*) remote_device, 1025230557Sjimharris (SCI_BASE_REQUEST_T*) io_request 1026230557Sjimharris ); 1027230557Sjimharris} 1028230557Sjimharris 1029230557Sjimharris/** 1030230557Sjimharris 1031230557Sjimharris * @brief This routine is to allocate the memory for creating a smp phy object. 1032230557Sjimharris * 1033230557Sjimharris * @param[in] scif_controller handle to frame controller 1034230557Sjimharris * 1035230557Sjimharris * @return SCIF_SAS_SMP_PHY_T * An allocated space for smp phy. If failed to allocate, 1036230557Sjimharris * return NULL. 1037230557Sjimharris */ 1038230557SjimharrisSCIF_SAS_SMP_PHY_T * scif_sas_controller_allocate_smp_phy( 1039230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 1040230557Sjimharris) 1041230557Sjimharris{ 1042230557Sjimharris SCIF_SAS_SMP_PHY_T * smp_phy; 1043230557Sjimharris 1044230557Sjimharris SCIF_LOG_TRACE(( 1045230557Sjimharris sci_base_object_get_logger(fw_controller), 1046230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER, 1047230557Sjimharris "scif_controller_allocate_smp_phy(0x%x) enter\n", 1048230557Sjimharris fw_controller 1049230557Sjimharris )); 1050230557Sjimharris 1051230557Sjimharris if( !sci_fast_list_is_empty(&fw_controller->smp_phy_memory_list) ) 1052230557Sjimharris { 1053230557Sjimharris smp_phy = (SCIF_SAS_SMP_PHY_T *) 1054230557Sjimharris sci_fast_list_remove_head(&fw_controller->smp_phy_memory_list); 1055230557Sjimharris 1056230557Sjimharris //clean the memory. 1057230557Sjimharris memset((char*)smp_phy, 1058230557Sjimharris 0, 1059230557Sjimharris sizeof(SCIF_SAS_SMP_PHY_T) 1060230557Sjimharris ); 1061230557Sjimharris 1062230557Sjimharris return smp_phy; 1063230557Sjimharris } 1064230557Sjimharris else 1065230557Sjimharris return NULL; 1066230557Sjimharris} 1067230557Sjimharris 1068230557Sjimharris/** 1069230557Sjimharris * @brief This routine is to free the memory for a released smp phy. 1070230557Sjimharris * 1071230557Sjimharris * @param[in] fw_controller The framework controller, a smp phy is released 1072230557Sjimharris * to its memory. 1073230557Sjimharris * @param[in] fw_smp_phy The smp phy to be freed. 1074230557Sjimharris * 1075230557Sjimharris * @return none 1076230557Sjimharris */ 1077230557Sjimharrisvoid scif_sas_controller_free_smp_phy( 1078230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 1079230557Sjimharris SCIF_SAS_SMP_PHY_T * smp_phy 1080230557Sjimharris) 1081230557Sjimharris{ 1082230557Sjimharris SCIF_LOG_TRACE(( 1083230557Sjimharris sci_base_object_get_logger(fw_controller), 1084230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER, 1085230557Sjimharris "scif_controller_free_smp_phy(0x%x, 0x%x) enter\n", 1086230557Sjimharris fw_controller, smp_phy 1087230557Sjimharris )); 1088230557Sjimharris 1089230557Sjimharris //return the memory to the list. 1090230557Sjimharris sci_fast_list_insert_tail( 1091230557Sjimharris &fw_controller->smp_phy_memory_list, 1092230557Sjimharris &smp_phy->list_element 1093230557Sjimharris ); 1094230557Sjimharris} 1095230557Sjimharris 1096230557Sjimharris 1097230557Sjimharris/** 1098230557Sjimharris * @brief This method clear affiliation for all the EA SATA devices associated 1099230557Sjimharris * to this controller. 1100230557Sjimharris * 1101230557Sjimharris * @param[in] fw_controller This parameter specifies the framework 1102230557Sjimharris * controller object for whose remote devices are to be stopped. 1103230557Sjimharris * 1104230557Sjimharris * @return This method returns a value indicating if the operation completed. 1105230557Sjimharris * @retval SCI_COMPLETE This value indicates that all the EA SATA devices' 1106230557Sjimharris * affiliation was cleared. 1107230557Sjimharris * @retval SCI_INCOMPLETE This value indicates clear affiliation activity is 1108230557Sjimharris * yet to be completed. 1109230557Sjimharris */ 1110230557SjimharrisSCI_STATUS scif_sas_controller_clear_affiliation( 1111230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 1112230557Sjimharris) 1113230557Sjimharris{ 1114230557Sjimharris U8 index; 1115230557Sjimharris SCI_STATUS status; 1116230557Sjimharris SCIF_SAS_DOMAIN_T * fw_domain; 1117230557Sjimharris 1118230557Sjimharris SCIF_LOG_TRACE(( 1119230557Sjimharris sci_base_object_get_logger(fw_controller), 1120230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER, 1121230557Sjimharris "scif_sas_controller_clear_affiliation(0x%x) enter\n", 1122230557Sjimharris fw_controller 1123230557Sjimharris )); 1124230557Sjimharris 1125230557Sjimharris index = fw_controller->current_domain_to_clear_affiliation; 1126230557Sjimharris 1127230557Sjimharris if (index < SCI_MAX_DOMAINS) 1128230557Sjimharris { 1129230557Sjimharris fw_domain = &fw_controller->domains[index]; 1130230557Sjimharris 1131230557Sjimharris //Need to stop all the on-going smp activities before clearing affiliation. 1132230557Sjimharris scif_sas_domain_cancel_smp_activities(fw_domain); 1133230557Sjimharris 1134230557Sjimharris scif_sas_domain_start_clear_affiliation(fw_domain); 1135230557Sjimharris 1136230557Sjimharris status = SCI_WARNING_SEQUENCE_INCOMPLETE; 1137230557Sjimharris } 1138230557Sjimharris else 1139230557Sjimharris { //the controller has done clear affiliation work to all its domains. 1140230557Sjimharris scif_sas_controller_continue_to_stop(fw_controller); 1141230557Sjimharris status = SCI_SUCCESS; 1142230557Sjimharris } 1143230557Sjimharris 1144230557Sjimharris return status; 1145230557Sjimharris} 1146230557Sjimharris 1147230557Sjimharris 1148230557Sjimharris/** 1149230557Sjimharris * @brief This method sets SCIF user parameters to 1150230557Sjimharris * default values. Users can override these values utilizing 1151230557Sjimharris * the sciF_user_parameters_set() methods. 1152230557Sjimharris * 1153230557Sjimharris * @param[in] controller This parameter specifies the controller for 1154230557Sjimharris * which to set the configuration parameters to their 1155230557Sjimharris * default values. 1156230557Sjimharris * 1157230557Sjimharris * @return none 1158230557Sjimharris */ 1159230557Sjimharrisvoid scif_sas_controller_set_default_config_parameters( 1160230557Sjimharris SCIF_SAS_CONTROLLER_T * this_controller 1161230557Sjimharris) 1162230557Sjimharris{ 1163230557Sjimharris SCIF_USER_PARAMETERS_T * scif_parms = &(this_controller->user_parameters); 1164230557Sjimharris 1165230557Sjimharris scif_parms->sas.is_sata_ncq_enabled = TRUE; 1166230557Sjimharris scif_parms->sas.max_ncq_depth = 32; 1167230557Sjimharris scif_parms->sas.is_sata_standby_timer_enabled = FALSE; 1168230557Sjimharris scif_parms->sas.is_non_zero_buffer_offsets_enabled = FALSE; 1169230557Sjimharris scif_parms->sas.reset_type = SCI_SAS_LOGICAL_UNIT_RESET; 1170230557Sjimharris scif_parms->sas.clear_affiliation_during_controller_stop = TRUE; 1171230557Sjimharris scif_parms->sas.ignore_fua = FALSE; 1172230557Sjimharris 1173230557Sjimharris} 1174230557Sjimharris 1175230557Sjimharris 1176230557Sjimharris/** 1177230557Sjimharris * @brief This method releases resource for framework controller and associated 1178230557Sjimharris * objects. 1179230557Sjimharris * 1180230557Sjimharris * @param[in] fw_controller This parameter specifies the framework 1181230557Sjimharris * controller and associated objects whose resources are to be released. 1182230557Sjimharris * 1183230557Sjimharris * @return This method returns a value indicating if the operation succeeded. 1184230557Sjimharris * @retval SCI_SUCCESS This value indicates that resource release succeeded. 1185230557Sjimharris * @retval SCI_FAILURE This value indicates certain failure during the process 1186230557Sjimharris * of resource release. 1187230557Sjimharris */ 1188230557SjimharrisSCI_STATUS scif_sas_controller_release_resource( 1189230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 1190230557Sjimharris) 1191230557Sjimharris{ 1192230557Sjimharris U8 index; 1193230557Sjimharris SCIF_SAS_DOMAIN_T * fw_domain; 1194230557Sjimharris 1195230557Sjimharris SCIF_LOG_TRACE(( 1196230557Sjimharris sci_base_object_get_logger(fw_controller), 1197230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER, 1198230557Sjimharris "scif_sas_controller_release_resource(0x%x) enter\n", 1199230557Sjimharris fw_controller 1200230557Sjimharris )); 1201230557Sjimharris 1202230557Sjimharris //currently the only resource to be released is domain's timer. 1203230557Sjimharris for (index = 0; index < SCI_MAX_DOMAINS; index++) 1204230557Sjimharris { 1205230557Sjimharris fw_domain = &fw_controller->domains[index]; 1206230557Sjimharris 1207230557Sjimharris scif_sas_domain_release_resource(fw_controller, fw_domain); 1208230557Sjimharris } 1209230557Sjimharris 1210230557Sjimharris return SCI_SUCCESS; 1211230557Sjimharris} 1212230557Sjimharris 1213230557Sjimharris 1214230557Sjimharris#ifdef SCI_LOGGING 1215230557Sjimharris/** 1216230557Sjimharris * This method will start state transition logging for the framework 1217230557Sjimharris * controller object. 1218230557Sjimharris * 1219230557Sjimharris * @param[in] fw_controller The framework controller object on which to 1220230557Sjimharris * observe state changes. 1221230557Sjimharris * 1222230557Sjimharris * @return none 1223230557Sjimharris */ 1224230557Sjimharrisvoid scif_sas_controller_initialize_state_logging( 1225230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 1226230557Sjimharris) 1227230557Sjimharris{ 1228230557Sjimharris sci_base_state_machine_logger_initialize( 1229230557Sjimharris &fw_controller->parent.state_machine_logger, 1230230557Sjimharris &fw_controller->parent.state_machine, 1231230557Sjimharris &fw_controller->parent.parent, 1232230557Sjimharris scif_cb_logger_log_states, 1233230557Sjimharris "SCIF_SAS_CONTROLLER_T", "base state machine", 1234230557Sjimharris SCIF_LOG_OBJECT_CONTROLLER 1235230557Sjimharris ); 1236230557Sjimharris} 1237230557Sjimharris 1238230557Sjimharris/** 1239230557Sjimharris * This method will remove the logging of state transitions from the framework 1240230557Sjimharris * controller object. 1241230557Sjimharris * 1242230557Sjimharris * @param[in] fw_controller The framework controller to change. 1243230557Sjimharris * 1244230557Sjimharris * @return none 1245230557Sjimharris */ 1246230557Sjimharrisvoid scif_sas_controller_deinitialize_state_logging( 1247230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller 1248230557Sjimharris) 1249230557Sjimharris{ 1250230557Sjimharris sci_base_state_machine_logger_deinitialize( 1251230557Sjimharris &fw_controller->parent.state_machine_logger, 1252230557Sjimharris &fw_controller->parent.state_machine 1253230557Sjimharris ); 1254230557Sjimharris} 1255230557Sjimharris#endif // SCI_LOGGING 1256