freebsd-dev/sys/dev/isci/scil/scif_sas_controller_state_handlers.c
Pedro F. Giffuni 718cf2ccb9 sys/dev: further adoption of SPDX licensing ID tags.
Mainly focus on files that use BSD 2-Clause license, however the tool I
was using misidentified many licenses so this was mostly a manual - error
prone - task.

The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.
2017-11-27 14:52:40 +00:00

1848 lines
67 KiB
C

/*-
* SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.GPL.
*
* BSD LICENSE
*
* Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/**
* @file
*
* @brief This file contains all of the state handler routines for each
* of the controller states defined by the SCI_BASE_CONTROLLER state
* machine.
*/
#include <dev/isci/scil/sci_util.h>
#include <dev/isci/scil/scic_controller.h>
#include <dev/isci/scil/scic_port.h>
#include <dev/isci/scil/scic_remote_device.h>
#include <dev/isci/scil/scic_io_request.h>
#include <dev/isci/scil/scif_sas_controller.h>
#include <dev/isci/scil/scif_sas_remote_device.h>
#include <dev/isci/scil/scif_sas_logger.h>
#include <dev/isci/scil/scif_sas_smp_remote_device.h>
//******************************************************************************
//* P R I V A T E M E T H O D S
//******************************************************************************
/**
* @brief This method simply executes the reset operation by entering
* the reset state and allowing the state to perform it's work.
*
* @param[in] fw_controller This parameter specifies the SAS framework
* controller for execute the reset.
*
* @return Indicate the status of the reset operation. Was it successful?
* @retval SCI_SUCCESS This value is returned if it was successfully reset.
*/
static
SCI_STATUS scif_sas_controller_execute_reset(
SCIF_SAS_CONTROLLER_T * fw_controller
)
{
SCI_STATUS status;
SCIF_LOG_TRACE((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_CONTROLLER_RESET,
"scif_sas_controller_execute_reset(0x%x) enter\n",
fw_controller
));
//clean the timer to avoid timer leak.
scif_sas_controller_release_resource(fw_controller);
sci_base_state_machine_change_state(
&fw_controller->parent.state_machine,
SCI_BASE_CONTROLLER_STATE_RESETTING
);
// Retrieve the status for the operations performed during the entrance
// to the resetting state were executing successfully.
status = fw_controller->operation_status;
fw_controller->operation_status = SCI_SUCCESS;
return status;
}
/**
* @brief This method checks that the memory descriptor list is valid
* and hasn't been corrupted in some way by the user.
*
* @param[in] fw_controller This parameter specifies the framework
* controller object for which to validation the MDL.
*
* @return This method returns a value indicating if the operation succeeded.
* @retval SCI_SUCCESS This value indicates that MDL is valid.
* @retval SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD This value indicates
* that some portion of the memory descriptor list is invalid.
*/
static
SCI_STATUS scif_sas_controller_validate_mdl(
SCIF_SAS_CONTROLLER_T * fw_controller
)
{
BOOL is_mde_list_valid;
// Currently there is only a single MDE in the list.
is_mde_list_valid = sci_base_mde_is_valid(
&fw_controller->mdes[SCIF_SAS_MDE_INTERNAL_IO],
4,
fw_controller->internal_request_entries *
scif_sas_internal_request_get_object_size(),
SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
);
if (is_mde_list_valid == FALSE)
return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
return SCI_SUCCESS;
}
/**
* @brief This method stops all the domains associated to this
* controller.
*
* @param[in] fw_controller This parameter specifies the framework
* controller object for whose remote devices are to be stopped.
*
* @return This method returns a value indicating if the operation succeeded.
* @retval SCI_SUCCESS This value indicates that all the devices are stopped.
* @retval SCI_FAILURE This value indicates certain failure during the process
* of stopping remote devices.
*/
static
SCI_STATUS scif_sas_controller_stop_domains(
SCIF_SAS_CONTROLLER_T * fw_controller
)
{
U8 index;
SCI_STATUS status = SCI_SUCCESS;
SCIF_SAS_DOMAIN_T * fw_domain;
SCIF_LOG_TRACE((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER,
"scif_sas_controller_stop_domains(0x%x) enter\n",
fw_controller
));
for (index = 0; index < SCI_MAX_DOMAINS && status == SCI_SUCCESS; index++)
{
fw_domain = &fw_controller->domains[index];
//Change this domain to STOPPING state. All the remote devices will be
//stopped subsquentially.
if (fw_domain->parent.state_machine.current_state_id ==
SCI_BASE_DOMAIN_STATE_READY
|| fw_domain->parent.state_machine.current_state_id ==
SCI_BASE_DOMAIN_STATE_DISCOVERING)
{
sci_base_state_machine_change_state(
&fw_domain->parent.state_machine, SCI_BASE_DOMAIN_STATE_STOPPING
);
}
}
return status;
}
/**
* @brief This method continue to stop the controller after clear affiliation
* is done.
*
* @param[in] fw_controller This parameter specifies the framework
* controller object to be stopped.
*
* @return This method returns a value indicating if the operation succeeded.
* @retval SCI_SUCCESS This value indicates the controller_stop succeeds.
* @retval SCI_FAILURE This value indicates certain failure during the process
* of stopping controller.
*/
SCI_STATUS scif_sas_controller_continue_to_stop(
SCIF_SAS_CONTROLLER_T * fw_controller
)
{
SCI_STATUS status;
SCIF_LOG_TRACE((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
"scif_sas_controller_continue_to_stop (0x%x).\n",
fw_controller
));
//stop all the domains and their remote devices.
status = scif_sas_controller_stop_domains(fw_controller);
if (status == SCI_SUCCESS)
{
// Attempt to stop the core controller.
status = scic_controller_stop(fw_controller->core_object, 0);
if (status != SCI_SUCCESS)
{
SCIF_LOG_ERROR((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
"Controller:0x%x Status:0x%x unable to stop controller.\n",
fw_controller, status
));
sci_base_state_machine_change_state(
&fw_controller->parent.state_machine,
SCI_BASE_CONTROLLER_STATE_FAILED
);
}
}
else
{
SCIF_LOG_ERROR((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
"Controller:0x%x Status:0x%x unable to stop domains.\n",
fw_controller, status
));
sci_base_state_machine_change_state(
&fw_controller->parent.state_machine,
SCI_BASE_CONTROLLER_STATE_FAILED
);
}
return status;
}
//******************************************************************************
//* R E S E T H A N D L E R S
//******************************************************************************
/**
* @brief This method provides RESET state specific handling for
* when a user attempts to initialize a controller. This is a legal
* state in which to attempt an initialize call.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform an initialize
* operation.
*
* @return This method returns an indication of whether the initialize
* operation succeeded.
* @retval SCI_SUCCESS This value when the initialization completes
* successfully.
*/
static
SCI_STATUS scif_sas_controller_reset_initialize_handler(
SCI_BASE_CONTROLLER_T * controller
)
{
SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)controller;
SCI_STATUS status;
U32 index;
SCIF_LOG_TRACE((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
"scif_sas_controller_reset_initialize_handler(0x%x) enter\n",
controller
));
sci_base_state_machine_change_state(
&fw_controller->parent.state_machine,
SCI_BASE_CONTROLLER_STATE_INITIALIZING
);
scif_sas_controller_build_mdl(fw_controller);
// Perform any domain object initialization that is necessary.
for (index = 0; index < SCI_MAX_DOMAINS; index++)
scif_sas_domain_initialize(&fw_controller->domains[index]);
scif_cb_lock_associate(fw_controller, &fw_controller->hprq.lock);
// Attempt to initialize the core controller.
status = scic_controller_initialize(fw_controller->core_object);
if (status == SCI_SUCCESS)
{
sci_base_state_machine_change_state(
&fw_controller->parent.state_machine,
SCI_BASE_CONTROLLER_STATE_INITIALIZED
);
}
if (status != SCI_SUCCESS)
{
// Initialization failed, Release resources and do not change state
scif_sas_controller_release_resource(fw_controller);
SCIF_LOG_ERROR((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
"Controller:0x%x Status:0x%x unable to successfully initialize.\n",
fw_controller, status
));
}
return status;
}
//******************************************************************************
//* I N I T I A L I Z E D H A N D L E R S
//******************************************************************************
/**
* @brief This method provides INITIALIZED state specific handling for
* when a user attempts to start a controller.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a start
* operation.
* @param[in] timeout This parameter specifies the timeout value (in
* milliseconds) to be utilized for this operation.
*
* @return This method returns an indication of whether the start operation
* succeeded.
* @retval SCI_SUCCESS This value is returned when the start operation
* begins successfully.
*/
static
SCI_STATUS scif_sas_controller_initialized_start_handler(
SCI_BASE_CONTROLLER_T * controller,
U32 timeout
)
{
SCI_STATUS status = SCI_SUCCESS;
SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)controller;
U16 index = 0;
SCI_PHYSICAL_MEMORY_DESCRIPTOR_T internal_reqeust_mde =
fw_controller->mdes[SCIF_SAS_MDE_INTERNAL_IO];
void * internal_request_virtual_address = internal_reqeust_mde.virtual_address;
POINTER_UINT address = (POINTER_UINT)internal_request_virtual_address;
SCIF_LOG_TRACE((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
"scif_sas_controller_initialized_start_handler(0x%x, 0x%x) enter\n",
controller, timeout
));
sci_base_state_machine_change_state(
&fw_controller->parent.state_machine,
SCI_BASE_CONTROLLER_STATE_STARTING
);
status = scif_sas_controller_validate_mdl(fw_controller);
// initialization work for internal request path. It must be done before
// starting domain.
if (status == SCI_SUCCESS)
{
// fill in the sci_pool for internal requests.
sci_pool_initialize(fw_controller->internal_request_memory_pool);
for (index = 0; index < fw_controller->internal_request_entries; index++)
{
sci_pool_put(fw_controller->internal_request_memory_pool, address);
address += scif_sas_internal_request_get_object_size();
}
// Using DPC for starting internal IOs, if yes, we need to intialize
// DPC here.
scif_cb_start_internal_io_task_create(fw_controller);
}
if (status == SCI_SUCCESS)
{
// Kick-start the domain state machines and, by association, the
// core port's.
// This will ensure we get valid port objects supplied with link up
// messages.
for (index = 0;
(index < SCI_MAX_DOMAINS) && (status == SCI_SUCCESS);
index++)
{
sci_base_state_machine_change_state(
&fw_controller->domains[index].parent.state_machine,
SCI_BASE_DOMAIN_STATE_STARTING
);
status = fw_controller->domains[index].operation.status;
}
}
// Validate that all the domain state machines began successfully.
if (status != SCI_SUCCESS)
{
SCIF_LOG_ERROR((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
"Controller:0x%x Domain:0x%x Status:0x%x unable to start\n",
fw_controller, index, status
));
return status;
}
// Attempt to start the core controller.
status = scic_controller_start(fw_controller->core_object, timeout);
if (status != SCI_SUCCESS)
{
SCIF_LOG_ERROR((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
"Controller:0x%x Status:0x%x unable to start controller.\n",
fw_controller, status
));
sci_base_state_machine_change_state(
&fw_controller->parent.state_machine,
SCI_BASE_CONTROLLER_STATE_FAILED
);
}
return status;
}
//******************************************************************************
//* R E A D Y H A N D L E R S
//******************************************************************************
/**
* @brief This method provides READY state specific handling for
* when a user attempts to stop a controller.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a stop
* operation.
* @param[in] timeout This parameter specifies the timeout value (in
* milliseconds) to be utilized for this operation.
*
* @return This method returns an indication of whether the stop operation
* succeeded.
* @retval SCI_SUCCESS This value is returned when the stop operation
* begins successfully.
*/
static
SCI_STATUS scif_sas_controller_ready_stop_handler(
SCI_BASE_CONTROLLER_T * controller,
U32 timeout
)
{
SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)controller;
SCIF_LOG_TRACE((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
"scif_sas_controller_ready_stop_handler(0x%x, 0x%x) enter\n",
controller, timeout
));
sci_base_state_machine_change_state(
&fw_controller->parent.state_machine,
SCI_BASE_CONTROLLER_STATE_STOPPING
);
if (fw_controller->user_parameters.sas.clear_affiliation_during_controller_stop)
{
fw_controller->current_domain_to_clear_affiliation = 0;
//clear affiliation first. After the last domain finishes clearing
//affiliation, it will call back to controller to continue to stop.
scif_sas_controller_clear_affiliation(fw_controller);
}
else
scif_sas_controller_continue_to_stop(fw_controller);
//Must return SUCCESS at this point.
return SCI_SUCCESS;
}
/**
* @brief This method provides READY state specific handling for
* when a user attempts to reset a controller.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a reset
* operation.
*
* @return This method returns an indication of whether the reset operation
* succeeded.
* @retval SCI_SUCCESS This value is returned when the reset operation
* completes successfully.
*/
static
SCI_STATUS scif_sas_controller_ready_reset_handler(
SCI_BASE_CONTROLLER_T * controller
)
{
return scif_sas_controller_execute_reset((SCIF_SAS_CONTROLLER_T*)controller);
}
/**
* @brief This method provides READY state specific handling for
* when a user attempts to start an IO request.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a start IO
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start IO
* operation.
* @param[in] io_request This parameter specifies the IO request to be
* started.
* @param[in] io_tag This parameter specifies the optional allocated
* IO tag. Please reference scif_controller_start_io() for
* more information.
*
* @return This method returns an indication of whether the start IO
* operation succeeded.
* @retval SCI_SUCCESS This value is returned when the start IO operation
* begins successfully.
*/
static
SCI_STATUS scif_sas_controller_ready_start_io_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * io_request,
U16 io_tag
)
{
SCI_STATUS status;
SCIF_SAS_IO_REQUEST_T *fw_io = (SCIF_SAS_IO_REQUEST_T*)io_request;
SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)controller;
SCIF_SAS_REMOTE_DEVICE_T *fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
remote_device;
SCIF_LOG_TRACE((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
"scif_sas_controller_ready_start_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
controller, remote_device, io_request, io_tag
));
status = fw_device->domain->state_handlers->start_io_handler(
&fw_device->domain->parent, remote_device, io_request
);
// Check to see that the other objects in the framework allowed
// this IO to be started.
if (status == SCI_SUCCESS)
{
// Ask the core to start processing for this IO request.
status = (SCI_STATUS)scic_controller_start_io(
fw_controller->core_object,
fw_device->core_object,
fw_io->parent.core_object,
io_tag
);
if (status == SCI_SUCCESS)
{
// We were able to start the core request. As a result,
// commit to starting the request for the framework by changing
// the state of the IO request.
sci_base_state_machine_change_state(
&io_request->state_machine, SCI_BASE_REQUEST_STATE_STARTED
);
}
else
{
// We were unable to start the core IO request. As a result,
// back out the start operation for the framework. It's easier to
// back out the framework start operation then to backout the core
// start IO operation.
fw_device->domain->state_handlers->complete_io_handler(
&fw_device->domain->parent, remote_device, io_request
);
// Invoke the IO completion handler. For most IOs, this does nothing
// since we are still in the constructed state. For NCQ, this will
// the return of the NCQ tag back to the remote device free pool.
fw_io->parent.state_handlers->complete_handler(io_request);
SCIF_LOG_WARNING((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x IORequest:0x%x Status:0x%x core IO start failed\n",
fw_controller, fw_io, status
));
}
}
else
{
SCIF_LOG_WARNING((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x IORequest:0x%x Status:0x%x IO start failed\n",
fw_controller, fw_io, status
));
}
return status;
}
/**
* @brief This method provides READY state specific handling for
* when a user attempts to complete an IO request.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a complete IO
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start IO
* operation.
* @param[in] io_request This parameter specifies the IO request to be
* started.
*
* @return This method returns an indication of whether the complete IO
* operation succeeded.
* @retval SCI_SUCCESS This value is returned when the complete IO operation
* begins successfully.
*/
static
SCI_STATUS scif_sas_controller_ready_complete_io_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * io_request
)
{
SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*)
controller;
SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
remote_device;
SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*)
io_request;
SCI_STATUS status;
SCI_STATUS core_status;
SCIF_LOG_TRACE((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
"scif_sas_controller_ready_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n",
controller, remote_device, io_request
));
fw_io->parent.state_handlers->destruct_handler(&fw_io->parent.parent);
status = fw_device->domain->state_handlers->complete_io_handler(
&fw_device->domain->parent, remote_device, io_request
);
// Ask the core to finish processing for this IO request.
core_status = scic_controller_complete_io(
fw_controller->core_object,
fw_device->core_object,
fw_io->parent.core_object
);
if (status == SCI_SUCCESS)
status = core_status;
if (status != SCI_SUCCESS)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x IORequest:0x%x Status:0x%x CoreStatus:0x%x "
"failure to complete IO\n",
fw_controller, fw_io, status, core_status
));
}
return status;
}
/**
* @brief This method provides READY state specific handling for
* when a user attempts to complete a high priority IO request.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a complete IO
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start IO
* operation.
* @param[in] io_request This parameter specifies the IO request to be
* started.
*
* @return This method returns an indication of whether the complete IO
* operation succeeded.
* @retval SCI_SUCCESS This value is returned when the complete IO operation
* begins successfully.
*/
static
SCI_STATUS scif_sas_controller_ready_complete_high_priority_io_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * io_request
)
{
SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*)
controller;
SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
remote_device;
SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*)
io_request;
SCI_IO_STATUS core_completion_status =
scic_request_get_sci_status(fw_io->parent.core_object);
U8 response_data[SCIF_SAS_RESPONSE_DATA_LENGTH];
SCI_STATUS status;
SCI_STATUS core_status;
SCIF_LOG_TRACE((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
"scif_sas_controller_ready_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x) enter\n",
controller, remote_device, io_request
));
// In high priority path, we ask the core to finish IO request before framework.
// retrieve and save io response from core now.
memcpy(response_data,
scic_io_request_get_response_iu_address(fw_io->parent.core_object),
SCIF_SAS_RESPONSE_DATA_LENGTH
);
core_status = scic_controller_complete_io(
fw_controller->core_object,
fw_device->core_object,
fw_io->parent.core_object
);
fw_io->parent.state_handlers->destruct_handler(&fw_io->parent.parent);
status = fw_device->domain->state_handlers->complete_high_priority_io_handler(
&fw_device->domain->parent,
remote_device,
io_request,
(void *)response_data,
core_completion_status
);
if (status == SCI_SUCCESS)
status = core_status;
if (status == SCI_SUCCESS)
{
//issue DPC to start next internal io in high prioriy queue.
if( !sci_pool_empty(fw_controller->hprq.pool) )
scif_cb_start_internal_io_task_schedule(
fw_controller,
scif_sas_controller_start_high_priority_io,
fw_controller
);
}
else
{
SCIF_LOG_WARNING((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x IORequest:0x%x Status:0x%x CoreStatus:0x%x "
"failure to complete IO\n",
fw_controller, fw_io, status, core_status
));
}
return status;
}
/**
* @brief This method provides READY state specific handling for
* when a user attempts to continue an IO request.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a continue IO
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start IO
* operation.
* @param[in] io_request This parameter specifies the IO request to be
* started.
*
* @return This method returns an indication of whether the continue IO
* operation succeeded.
* @retval SCI_SUCCESS This value is returned when the continue IO operation
* begins successfully.
*/
static
SCI_STATUS scif_sas_controller_ready_continue_io_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * io_request
)
{
SCIF_LOG_TRACE((
sci_base_object_get_logger(controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
"scif_sas_controller_ready_continue_io_handler(0x%x, 0x%x, 0x%x) enter\n",
controller, remote_device, io_request
));
/// @todo Function unimplemented. fix return code handling.
return SCI_FAILURE;
}
/**
* @brief This method provides READY state specific handling for
* when a user attempts to start a task request.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a start task
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start
* task operation.
* @param[in] task_request This parameter specifies the task management
* request to be started.
* @param[in] io_tag This parameter specifies the optional allocated
* IO tag. Please reference scif_controller_start_task() for
* more information.
*
* @return This method returns an indication of whether the start task
* operation succeeded.
* @retval SCI_SUCCESS This value is returned when the start task operation
* begins successfully.
*/
static
SCI_STATUS scif_sas_controller_ready_start_task_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * task_request,
U16 io_tag
)
{
SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*)
controller;
SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
remote_device;
SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*)task_request;
SCI_STATUS status;
SCIF_LOG_TRACE((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
"scif_sas_controller_ready_start_task_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
controller, remote_device, task_request, io_tag
));
status = fw_device->domain->state_handlers->start_task_handler(
&fw_device->domain->parent, remote_device, task_request
);
if (status == SCI_SUCCESS)
{
if (scif_sas_task_request_get_function(fw_task)
== SCI_SAS_HARD_RESET)
{
// Go off to special target reset path. Don't start task to core.
scif_sas_remote_device_target_reset(
fw_device,
(SCIF_SAS_REQUEST_T *)fw_task
);
return SCI_SUCCESS;
}
// Ask the core to start processing for this task request.
status = (SCI_STATUS)scic_controller_start_task(
fw_controller->core_object,
fw_device->core_object,
fw_task->parent.core_object,
io_tag
);
if (status == SCI_SUCCESS)
{
// We were able to start the core request. As a result,
// commit to starting the request for the framework by changing
// the state of the task request.
fw_task->parent.state_handlers->start_handler(&fw_task->parent.parent);
}
else
{
// We were unable to start the core task request. As a result,
// back out the start operation for the framework. It's easier to
// back out the framework start operation then to backout the core
// start task operation.
fw_device->domain->state_handlers->complete_task_handler(
&fw_device->domain->parent, remote_device, task_request
);
if (status == SCI_SUCCESS)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x TaskRequest:0x%x Status:0x%x core start failed\n",
fw_controller, fw_task, status
));
}
}
}
else
{
SCIF_LOG_WARNING((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x TaskRequest:0x%x Status:0x%x Task start failed\n",
fw_controller, fw_task, status
));
}
return status;
}
/**
* @brief This method provides READY state specific handling for
* when a user attempts to complete a task request.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a complete task
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start
* task operation.
* @param[in] task_request This parameter specifies the task management
* request to be started.
*
* @return This method returns an indication of whether the complete task
* operation succeeded.
* @retval SCI_SUCCESS This value is returned when the complete task operation
* begins successfully.
*/
static
SCI_STATUS scif_sas_controller_ready_complete_task_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * task_request
)
{
SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)controller;
SCIF_SAS_REMOTE_DEVICE_T *fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)remote_device;
SCIF_SAS_TASK_REQUEST_T *fw_task = (SCIF_SAS_TASK_REQUEST_T*)task_request;
SCI_STATUS status;
SCI_STATUS core_status;
SCIF_LOG_TRACE((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
"scif_sas_controller_ready_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n",
controller, remote_device, task_request
));
status = fw_device->domain->state_handlers->complete_task_handler(
&fw_device->domain->parent, remote_device, task_request
);
if (scif_sas_task_request_get_function(fw_task)
== SCI_SAS_HARD_RESET)
{
//No more things to do in the core, since this task is for Target Reset.
return status;
}
fw_task->parent.state_handlers->destruct_handler(&fw_task->parent.parent);
// Ask the core to finish processing for this task request.
core_status = scic_controller_complete_task(
fw_controller->core_object,
fw_device->core_object,
fw_task->parent.core_object
);
if (status == SCI_SUCCESS)
status = core_status;
if (status != SCI_SUCCESS)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x TaskRequest:0x%x Status:0x%x CoreStatus:0x%x "
"failed to complete\n",
fw_controller, fw_task, status, core_status
));
}
return status;
}
/**
* @brief This method provides common handling for several states
* when a user attempts to start an internal request.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a start IO
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start IO
* operation.
* @param[in] io_request This parameter specifies the IO request to be
* started.
* @param[in] io_tag This parameter specifies the optional allocated
* IO tag. Please reference scif_controller_start_io() for
* more information.
*
* @return This method returns an indication of whether the start IO
* operation succeeded.
* @retval SCI_SUCCESS This value is returned when the start IO operation
* begins successfully.
*/
static
SCI_STATUS scif_sas_controller_common_start_high_priority_io_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * io_request,
U16 io_tag
)
{
SCI_STATUS status;
SCIF_SAS_IO_REQUEST_T *fw_io = (SCIF_SAS_IO_REQUEST_T*)io_request;
SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)controller;
SCIF_SAS_REMOTE_DEVICE_T *fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
remote_device;
status = fw_device->domain->state_handlers->start_high_priority_io_handler(
&fw_device->domain->parent, remote_device, io_request
);
// Check to see that the other objects in the framework allowed
// this IO to be started.
if (status == SCI_SUCCESS)
{
// Ask the core to start processing for this IO request.
status = (SCI_STATUS)scic_controller_start_io(
fw_controller->core_object,
fw_device->core_object,
fw_io->parent.core_object,
io_tag
);
if (status == SCI_SUCCESS)
{
// We were able to start the core request. As a result,
// commit to starting the request for the framework by changing
// the state of the IO request.
sci_base_state_machine_change_state(
&io_request->state_machine, SCI_BASE_REQUEST_STATE_STARTED
);
}
else
{
// We were unable to start the core IO request. As a result,
// back out the start operation for the framework. It's easier to
// back out the framework start operation then to backout the core
// start IO operation.
fw_device->domain->state_handlers->complete_io_handler(
&fw_device->domain->parent, remote_device, io_request
);
// Invoke the IO completion handler. For most IOs, this does nothing
// since we are still in the constructed state. For NCQ, this will
// the return of the NCQ tag back to the remote device free pool.
fw_io->parent.state_handlers->complete_handler(io_request);
SCIF_LOG_WARNING((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x IORequest:0x%x Status:0x%x core IO start failed\n",
fw_controller, fw_io, status
));
}
}
else
{
SCIF_LOG_WARNING((
sci_base_object_get_logger(fw_controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x IORequest:0x%x Status:0x%x IO start failed\n",
fw_controller, fw_io, status
));
// Invoke the IO completion handler. For most IOs, this does nothing
// since we are still in the constructed state. For NCQ, this will
// the return of the NCQ tag back to the remote device free pool.
fw_io->parent.state_handlers->complete_handler(io_request);
}
if (fw_io->parent.is_internal && status != SCI_SUCCESS )
{
SCIC_TRANSPORT_PROTOCOL protocol =
scic_io_request_get_protocol(fw_io->parent.core_object);
U8 retry_count = fw_io->retry_count;
scif_sas_internal_io_request_destruct(
fw_device->domain->controller,
(SCIF_SAS_INTERNAL_IO_REQUEST_T *)fw_io
);
if ( protocol == SCIC_SMP_PROTOCOL )
{
if (fw_device->protocol_device.smp_device.smp_activity_timer != NULL)
{
//destroy the smp_activity_timer
scif_cb_timer_destroy (
fw_controller,
fw_device->protocol_device.smp_device.smp_activity_timer
);
fw_device->protocol_device.smp_device.smp_activity_timer = NULL;
}
//we should retry for finite times
if ( retry_count < SCIF_SAS_IO_RETRY_LIMIT)
{
//An internal smp request failed being started, most likely due to remote device
//is not in ready state, for example, UPDATING_PORT_WIDTH state. In this case,
//we should retry the IO.
scif_sas_smp_remote_device_retry_internal_io(
(SCIF_SAS_REMOTE_DEVICE_T *)remote_device,
retry_count,
SMP_REQUEST_RETRY_WAIT_DURATION
);
}
}
}
return status;
}
/**
* @brief This method provides READY state specific handling for
* when a user attempts to start an internal request. If the high
* priority IO is also internal, this method will schedule its timer.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a start IO
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start IO
* operation.
* @param[in] io_request This parameter specifies the IO request to be
* started.
* @param[in] io_tag This parameter specifies the optional allocated
* IO tag. Please reference scif_controller_start_io() for
* more information.
*
* @return This method returns an indication of whether the start IO
* operation succeeded.
* @retval SCI_SUCCESS This value is returned when the start IO operation
* begins successfully.
*/
static
SCI_STATUS scif_sas_controller_ready_start_high_priority_io_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * io_request,
U16 io_tag
)
{
SCI_STATUS status;
SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *)io_request;
SCIF_LOG_TRACE((
sci_base_object_get_logger(controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
"scif_sas_controller_ready_start_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
controller, remote_device, io_request, io_tag
));
status = scif_sas_controller_common_start_high_priority_io_handler(
controller, remote_device, io_request, io_tag);
if (status == SCI_SUCCESS)
{
//External io could also be put in high priority queue. i.e. the
//smp request for EA Target Reset.
if (fw_io->parent.is_internal)
{
SCIF_SAS_INTERNAL_IO_REQUEST_T * fw_internal_io =
(SCIF_SAS_INTERNAL_IO_REQUEST_T *)fw_io;
//start the timer for internal io
scif_cb_timer_start(
(SCI_CONTROLLER_HANDLE_T)controller,
fw_internal_io->internal_io_timer,
SCIF_SAS_INTERNAL_REQUEST_TIMEOUT
);
}
}
else
{
//If failed to start, most likely the device or domain is not in
//correct state, and the IO has been cleaned up in controller's start
//high priority IO handler. We should just continue to start the next
//IO in the HP queue.
SCIF_LOG_TRACE((
sci_base_object_get_logger(controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
"scif_controller_start_high_priority_io(0x%x, 0x%x), starting io failed\n",
controller, fw_io
));
}
return status;
}
//******************************************************************************
//* S T O P P I N G H A N D L E R S
//******************************************************************************
/**
* @brief This method provides STOPPING state specific handling for
* when a user attempts to start an internal request. Note that we don't
* start the timer for internal IO during controller stopping state.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a start IO
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start IO
* operation.
* @param[in] io_request This parameter specifies the IO request to be
* started.
* @param[in] io_tag This parameter specifies the optional allocated
* IO tag. Please reference scif_controller_start_io() for
* more information.
*
* @return This method returns an indication of whether the start IO
* operation succeeded.
* @retval SCI_SUCCESS This value is returned when the start IO operation
* begins successfully.
*/
static
SCI_STATUS scif_sas_controller_stopping_start_high_priority_io_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * io_request,
U16 io_tag
)
{
SCIF_LOG_TRACE((
sci_base_object_get_logger(controller),
SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
"scif_sas_controller_stopping_start_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
controller, remote_device, io_request, io_tag
));
return scif_sas_controller_common_start_high_priority_io_handler(
controller, remote_device, io_request, io_tag);
}
//******************************************************************************
//* S T O P P E D H A N D L E R S
//******************************************************************************
/**
* @brief This method provides STOPPED state specific handling for
* when a user attempts to reset a controller.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a reset
* operation.
*
* @return This method returns an indication of whether the reset operation
* succeeded.
* @retval SCI_SUCCESS This value is returned when the reset operation
* completes successfully.
*/
static
SCI_STATUS scif_sas_controller_stopped_reset_handler(
SCI_BASE_CONTROLLER_T * controller
)
{
return scif_sas_controller_execute_reset((SCIF_SAS_CONTROLLER_T*)controller);
}
//******************************************************************************
//* F A I L E D H A N D L E R S
//******************************************************************************
/**
* @brief This method provides FAILED state specific handling for
* when a user attempts to reset a controller.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a reset
* operation.
*
* @return This method returns an indication of whether the reset operation
* succeeded.
* @retval SCI_SUCCESS This value is returned when the reset operation
* completes successfully.
*/
static
SCI_STATUS scif_sas_controller_failed_reset_handler(
SCI_BASE_CONTROLLER_T * controller
)
{
return scif_sas_controller_execute_reset((SCIF_SAS_CONTROLLER_T*)controller);
}
//******************************************************************************
//* D E F A U L T H A N D L E R S
//******************************************************************************
/**
* @brief This method provides default handling (i.e. returns an error)
* when a user attempts to start a controller and a start operation
* is not allowed.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a start operation.
* @param[in] timeout This parameter specifies the timeout value (in
* milliseconds) to be utilized for this operation.
*
* @return This method returns an indication that start operations are not
* allowed.
* @retval SCI_FAILURE_INVALID_STATE This value is always returned.
*/
static
SCI_STATUS scif_sas_controller_default_start_handler(
SCI_BASE_CONTROLLER_T * controller,
U32 timeout
)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x State:0x%x invalid state to start controller.\n",
controller,
sci_base_state_machine_get_state(
&((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
));
return SCI_FAILURE_INVALID_STATE;
}
/**
* @brief This method provides default handling (i.e. returns an error)
* when a user attempts to stop a controller and a stop operation
* is not allowed.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a stop operation.
* @param[in] timeout This parameter specifies the timeout value (in
* milliseconds) to be utilized for this operation.
*
* @return This method returns an indication that stop operations are not
* allowed.
* @retval SCI_FAILURE_INVALID_STATE This value is always returned.
*/
static
SCI_STATUS scif_sas_controller_default_stop_handler(
SCI_BASE_CONTROLLER_T * controller,
U32 timeout
)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x State:0x%x invalid state to stop controller.\n",
controller,
sci_base_state_machine_get_state(
&((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
));
return SCI_FAILURE_INVALID_STATE;
}
/**
* @brief This method provides default handling (i.e. returns an error)
* when a user attempts to reset a controller and a reset operation
* is not allowed.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a reset operation.
*
* @return This method returns an indication that reset operations are not
* allowed.
* @retval SCI_FAILURE_INVALID_STATE This value is always returned.
*/
static
SCI_STATUS scif_sas_controller_default_reset_handler(
SCI_BASE_CONTROLLER_T * controller
)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x State:0x%x invalid state to reset controller.\n",
controller,
sci_base_state_machine_get_state(
&((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
));
return SCI_FAILURE_INVALID_STATE;
}
/**
* @brief This method provides default handling (i.e. returns an error)
* when a user attempts to initialize a controller and an initialize
* operation is not allowed.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform an initialize
* operation.
*
* @return This method returns an indication that initialize operations
* are not allowed.
* @retval SCI_FAILURE_INVALID_STATE This value is always returned.
*/
static
SCI_STATUS scif_sas_controller_default_initialize_handler(
SCI_BASE_CONTROLLER_T * controller
)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x State:0x%x invalid state to initialize controller.\n",
controller,
sci_base_state_machine_get_state(
&((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
));
return SCI_FAILURE_INVALID_STATE;
}
/**
* @brief This method provides default handling (i.e. returns an error)
* when a user attempts to start an IO on a controller and a start
* IO operation is not allowed.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a start IO
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start IO
* operation.
* @param[in] io_request This parameter specifies the IO request to be
* started.
* @param[in] io_tag This parameter specifies the optional allocated
* IO tag. Please reference scif_controller_start_io() for
* more information.
*
* @return This method returns an indication that start IO operations
* are not allowed.
* @retval SCI_FAILURE_INVALID_STATE This value is always returned.
*/
static
SCI_STATUS scif_sas_controller_default_start_io_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * io_request,
U16 io_tag
)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x State:0x%x invalid state to start IO.\n",
controller,
sci_base_state_machine_get_state(
&((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
));
return SCI_FAILURE_INVALID_STATE;
}
/**
* @brief This method provides default handling (i.e. returns an error)
* when a user attempts to complete an IO on a controller and a
* complete IO operation is not allowed.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a complete IO
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start IO
* operation.
* @param[in] io_request This parameter specifies the IO request to be
* started.
*
* @return This method returns an indication that complete IO operations
* are not allowed.
* @retval SCI_FAILURE_INVALID_STATE This value is always returned.
*/
static
SCI_STATUS scif_sas_controller_default_complete_io_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * io_request
)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x State:0x%x invalid state to complete IO.\n",
controller,
sci_base_state_machine_get_state(
&((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
));
return SCI_FAILURE_INVALID_STATE;
}
/**
* @brief This method provides default handling (i.e. returns an error)
* when a user attempts to continue an IO on a controller and a
* continue IO operation is not allowed.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a continue IO
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start IO
* operation.
* @param[in] io_request This parameter specifies the IO request to be
* started.
*
* @return This method returns an indication that continue IO operations
* are not allowed.
* @retval SCI_FAILURE_INVALID_STATE This value is always returned.
*/
static
SCI_STATUS scif_sas_controller_default_continue_io_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * io_request
)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x State:0x%x invalid state to continue IO.\n",
controller,
sci_base_state_machine_get_state(
&((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
));
return SCI_FAILURE_INVALID_STATE;
}
/**
* @brief This method provides default handling (i.e. returns an error)
* when a user attempts to start a task on a controller and a start
* task operation is not allowed.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a start task
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start
* task operation.
* @param[in] task_request This parameter specifies the task management
* request to be started.
* @param[in] io_tag This parameter specifies the optional allocated
* IO tag. Please reference scif_controller_start_task() for
* more information.
*
* @return This method returns an indication that start task operations
* are not allowed.
* @retval SCI_FAILURE_INVALID_STATE This value is always returned.
*/
static
SCI_STATUS scif_sas_controller_default_start_task_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * task_request,
U16 io_tag
)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x State:0x%x invalid state to start task mgmt.\n",
controller,
sci_base_state_machine_get_state(
&((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
));
return SCI_FAILURE_INVALID_STATE;
}
/**
* @brief This method provides default handling (i.e. returns an error)
* when a user attempts to complete a task on a controller and a
* complete task operation is not allowed.
*
* @param[in] controller This parameter specifies the controller object
* on which the user is attempting to perform a complete task
* operation.
* @param[in] remote_device This parameter specifies the remote deivce
* object on which the user is attempting to perform a start
* task operation.
* @param[in] task_request This parameter specifies the task management
* request to be started.
*
* @return This method returns an indication that complete task operations
* are not allowed.
* @retval SCI_FAILURE_INVALID_STATE This value is always returned.
*/
static
SCI_STATUS scif_sas_controller_default_complete_task_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * task_request
)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x State:0x%x invalid state to complete task mgmt.\n",
controller,
sci_base_state_machine_get_state(
&((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
));
return SCI_FAILURE_INVALID_STATE;
}
static
SCI_STATUS scif_sas_controller_failed_state_start_io_handler(
SCI_BASE_CONTROLLER_T * controller,
SCI_BASE_REMOTE_DEVICE_T * remote_device,
SCI_BASE_REQUEST_T * io_request,
U16 io_tag
)
{
SCIF_LOG_WARNING((
sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
SCIF_LOG_OBJECT_CONTROLLER,
"Controller:0x%x State:0x%x invalid state to start IO.\n",
controller,
sci_base_state_machine_get_state(
&((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
));
return SCI_FAILURE;
}
#define scif_sas_controller_stopping_complete_io_handler \
scif_sas_controller_ready_complete_io_handler
#define scif_sas_controller_stopping_complete_task_handler \
scif_sas_controller_ready_complete_task_handler
#define scif_sas_controller_default_start_high_priority_io_handler \
scif_sas_controller_default_start_io_handler
#define scif_sas_controller_default_complete_high_priority_io_handler \
scif_sas_controller_default_complete_io_handler
#define scif_sas_controller_stopping_complete_high_priority_io_handler \
scif_sas_controller_ready_complete_high_priority_io_handler
SCI_BASE_CONTROLLER_STATE_HANDLER_T
scif_sas_controller_state_handler_table[SCI_BASE_CONTROLLER_MAX_STATES] =
{
// SCI_BASE_CONTROLLER_STATE_INITIAL
{
scif_sas_controller_default_start_handler,
scif_sas_controller_default_stop_handler,
scif_sas_controller_default_reset_handler,
scif_sas_controller_default_initialize_handler,
scif_sas_controller_default_start_io_handler,
scif_sas_controller_default_start_high_priority_io_handler,
scif_sas_controller_default_complete_io_handler,
scif_sas_controller_default_complete_high_priority_io_handler,
scif_sas_controller_default_continue_io_handler,
scif_sas_controller_default_start_task_handler,
scif_sas_controller_default_complete_task_handler
},
// SCI_BASE_CONTROLLER_STATE_RESET
{
scif_sas_controller_default_start_handler,
scif_sas_controller_default_stop_handler,
scif_sas_controller_default_reset_handler,
scif_sas_controller_reset_initialize_handler,
scif_sas_controller_default_start_io_handler,
scif_sas_controller_default_start_high_priority_io_handler,
scif_sas_controller_default_complete_io_handler,
scif_sas_controller_default_complete_high_priority_io_handler,
scif_sas_controller_default_continue_io_handler,
scif_sas_controller_default_start_task_handler,
scif_sas_controller_default_complete_task_handler
},
// SCI_BASE_CONTROLLER_STATE_INITIALIZING
{
scif_sas_controller_default_start_handler,
scif_sas_controller_default_stop_handler,
scif_sas_controller_default_reset_handler,
scif_sas_controller_default_initialize_handler,
scif_sas_controller_default_start_io_handler,
scif_sas_controller_default_start_high_priority_io_handler,
scif_sas_controller_default_complete_io_handler,
scif_sas_controller_default_complete_high_priority_io_handler,
scif_sas_controller_default_continue_io_handler,
scif_sas_controller_default_start_task_handler,
scif_sas_controller_default_complete_task_handler
},
// SCI_BASE_CONTROLLER_STATE_INITIALIZED
{
scif_sas_controller_initialized_start_handler,
scif_sas_controller_default_stop_handler,
scif_sas_controller_default_reset_handler,
scif_sas_controller_default_initialize_handler,
scif_sas_controller_default_start_io_handler,
scif_sas_controller_default_start_high_priority_io_handler,
scif_sas_controller_default_complete_io_handler,
scif_sas_controller_default_complete_high_priority_io_handler,
scif_sas_controller_default_continue_io_handler,
scif_sas_controller_default_start_task_handler,
scif_sas_controller_default_complete_task_handler
},
// SCI_BASE_CONTROLLER_STATE_STARTING
{
scif_sas_controller_default_start_handler,
scif_sas_controller_default_stop_handler,
scif_sas_controller_default_reset_handler,
scif_sas_controller_default_initialize_handler,
scif_sas_controller_default_start_io_handler,
scif_sas_controller_default_start_high_priority_io_handler,
scif_sas_controller_default_complete_io_handler,
scif_sas_controller_default_complete_high_priority_io_handler,
scif_sas_controller_default_continue_io_handler,
scif_sas_controller_default_start_task_handler,
scif_sas_controller_default_complete_task_handler
},
// SCI_BASE_CONTROLLER_STATE_READY
{
scif_sas_controller_default_start_handler,
scif_sas_controller_ready_stop_handler,
scif_sas_controller_ready_reset_handler,
scif_sas_controller_default_initialize_handler,
scif_sas_controller_ready_start_io_handler,
scif_sas_controller_ready_start_high_priority_io_handler,
scif_sas_controller_ready_complete_io_handler,
scif_sas_controller_ready_complete_high_priority_io_handler,
scif_sas_controller_ready_continue_io_handler,
scif_sas_controller_ready_start_task_handler,
scif_sas_controller_ready_complete_task_handler
},
// SCI_BASE_CONTROLLER_STATE_RESETTING
{
scif_sas_controller_default_start_handler,
scif_sas_controller_default_stop_handler,
scif_sas_controller_default_reset_handler,
scif_sas_controller_default_initialize_handler,
scif_sas_controller_default_start_io_handler,
scif_sas_controller_default_start_high_priority_io_handler,
scif_sas_controller_default_complete_io_handler,
scif_sas_controller_default_complete_high_priority_io_handler,
scif_sas_controller_default_continue_io_handler,
scif_sas_controller_default_start_task_handler,
scif_sas_controller_default_complete_task_handler
},
// SCI_BASE_CONTROLLER_STATE_STOPPING
{
scif_sas_controller_default_start_handler,
scif_sas_controller_default_stop_handler,
scif_sas_controller_default_reset_handler,
scif_sas_controller_default_initialize_handler,
scif_sas_controller_default_start_io_handler,
scif_sas_controller_stopping_start_high_priority_io_handler,
scif_sas_controller_stopping_complete_io_handler,
scif_sas_controller_stopping_complete_high_priority_io_handler,
scif_sas_controller_default_continue_io_handler,
scif_sas_controller_default_start_task_handler, /**@todo Allow in core?*/
scif_sas_controller_stopping_complete_task_handler
},
// SCI_BASE_CONTROLLER_STATE_STOPPED
{
scif_sas_controller_default_start_handler,
scif_sas_controller_default_stop_handler,
scif_sas_controller_stopped_reset_handler,
scif_sas_controller_default_initialize_handler,
scif_sas_controller_default_start_io_handler,
scif_sas_controller_default_start_high_priority_io_handler,
scif_sas_controller_default_complete_io_handler,
scif_sas_controller_default_complete_high_priority_io_handler,
scif_sas_controller_default_continue_io_handler,
scif_sas_controller_default_start_task_handler,
scif_sas_controller_default_complete_task_handler
},
// SCI_BASE_CONTROLLER_STATE_FAILED
{
scif_sas_controller_default_start_handler,
scif_sas_controller_default_stop_handler,
scif_sas_controller_failed_reset_handler,
scif_sas_controller_default_initialize_handler,
scif_sas_controller_failed_state_start_io_handler,
scif_sas_controller_failed_state_start_io_handler,
scif_sas_controller_default_complete_io_handler,
scif_sas_controller_default_complete_high_priority_io_handler,
scif_sas_controller_default_continue_io_handler,
scif_sas_controller_default_start_task_handler,
scif_sas_controller_default_complete_task_handler
}
};