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 This file contains the SMP remote device 60230557Sjimharris * object methods and it's state machines. 61230557Sjimharris */ 62230557Sjimharris 63230557Sjimharris#include <dev/isci/scil/scic_user_callback.h> 64230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h> 65230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h> 66230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h> 67230557Sjimharris#include <dev/isci/scil/scic_sds_port.h> 68230557Sjimharris#include <dev/isci/scil/scic_sds_request.h> 69230557Sjimharris#include <dev/isci/scil/scu_event_codes.h> 70230557Sjimharris#include <dev/isci/scil/scu_task_context.h> 71230557Sjimharris#include <dev/isci/scil/scic_remote_device.h> 72230557Sjimharris 73230557Sjimharris//***************************************************************************** 74230557Sjimharris//* SMP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS 75230557Sjimharris//***************************************************************************** 76230557Sjimharris 77230557Sjimharris/** 78230557Sjimharris * This method will handle the start io operation for a SMP device that is in 79230557Sjimharris * the idle state. 80230557Sjimharris * 81230557Sjimharris * @param [in] device The device the io is sent to. 82230557Sjimharris * @param [in] request The io to start. 83230557Sjimharris * 84230557Sjimharris * @return SCI_STATUS 85230557Sjimharris */ 86230557Sjimharrisstatic 87230557SjimharrisSCI_STATUS scic_sds_smp_remote_device_ready_idle_substate_start_io_handler( 88230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * device, 89230557Sjimharris SCI_BASE_REQUEST_T * request 90230557Sjimharris) 91230557Sjimharris{ 92230557Sjimharris SCI_STATUS status; 93230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 94230557Sjimharris SCIC_SDS_REQUEST_T * io_request = (SCIC_SDS_REQUEST_T *)request; 95230557Sjimharris 96230557Sjimharris // Will the port allow the io request to start? 97230557Sjimharris status = this_device->owning_port->state_handlers->start_io_handler( 98230557Sjimharris this_device->owning_port, 99230557Sjimharris this_device, 100230557Sjimharris io_request 101230557Sjimharris ); 102230557Sjimharris 103230557Sjimharris if (status == SCI_SUCCESS) 104230557Sjimharris { 105230557Sjimharris status = 106230557Sjimharris scic_sds_remote_node_context_start_io(this_device->rnc, io_request); 107230557Sjimharris 108230557Sjimharris if (status == SCI_SUCCESS) 109230557Sjimharris { 110230557Sjimharris status = scic_sds_request_start(io_request); 111230557Sjimharris } 112230557Sjimharris 113230557Sjimharris if (status == SCI_SUCCESS) 114230557Sjimharris { 115230557Sjimharris this_device->working_request = io_request; 116230557Sjimharris 117230557Sjimharris sci_base_state_machine_change_state( 118230557Sjimharris &this_device->ready_substate_machine, 119230557Sjimharris SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD 120230557Sjimharris ); 121230557Sjimharris } 122230557Sjimharris 123230557Sjimharris scic_sds_remote_device_start_request(this_device, io_request, status); 124230557Sjimharris } 125230557Sjimharris 126230557Sjimharris return status; 127230557Sjimharris} 128230557Sjimharris 129230557Sjimharris 130230557Sjimharris//****************************************************************************** 131230557Sjimharris//* SMP REMOTE DEVICE READY SUBSTATE CMD HANDLERS 132230557Sjimharris//****************************************************************************** 133230557Sjimharris/** 134230557Sjimharris * This device is already handling a command it can not accept new commands 135230557Sjimharris * until this one is complete. 136230557Sjimharris * 137230557Sjimharris * @param[in] device This is the device object that is receiving the IO. 138230557Sjimharris * 139230557Sjimharris * @param[in] request The io to start. 140230557Sjimharris * 141230557Sjimharris * @return SCI_STATUS 142230557Sjimharris */ 143230557Sjimharrisstatic 144230557SjimharrisSCI_STATUS scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler( 145230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * device, 146230557Sjimharris SCI_BASE_REQUEST_T * request 147230557Sjimharris) 148230557Sjimharris{ 149230557Sjimharris return SCI_FAILURE_INVALID_STATE; 150230557Sjimharris} 151230557Sjimharris 152230557Sjimharris 153230557Sjimharris/** 154230557Sjimharris * @brief this is the complete_io_handler for smp device at ready cmd substate. 155230557Sjimharris * 156230557Sjimharris * @param[in] device This is the device object that is receiving the IO. 157230557Sjimharris * @param[in] request The io to start. 158230557Sjimharris * 159230557Sjimharris * @return SCI_STATUS 160230557Sjimharris */ 161230557Sjimharrisstatic 162230557SjimharrisSCI_STATUS scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler( 163230557Sjimharris SCI_BASE_REMOTE_DEVICE_T * device, 164230557Sjimharris SCI_BASE_REQUEST_T * request 165230557Sjimharris) 166230557Sjimharris{ 167230557Sjimharris SCI_STATUS status; 168230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device; 169230557Sjimharris SCIC_SDS_REQUEST_T * the_request; 170230557Sjimharris 171230557Sjimharris this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 172230557Sjimharris the_request = (SCIC_SDS_REQUEST_T *)request; 173230557Sjimharris 174230557Sjimharris status = scic_sds_io_request_complete(the_request); 175230557Sjimharris 176230557Sjimharris if (status == SCI_SUCCESS) 177230557Sjimharris { 178230557Sjimharris status = scic_sds_port_complete_io( 179230557Sjimharris this_device->owning_port, this_device, the_request); 180230557Sjimharris 181230557Sjimharris if (status == SCI_SUCCESS) 182230557Sjimharris { 183230557Sjimharris scic_sds_remote_device_decrement_request_count(this_device); 184230557Sjimharris sci_base_state_machine_change_state( 185230557Sjimharris &this_device->ready_substate_machine, 186230557Sjimharris SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE 187230557Sjimharris ); 188230557Sjimharris } 189230557Sjimharris else 190230557Sjimharris { 191230557Sjimharris SCIC_LOG_ERROR(( 192230557Sjimharris sci_base_object_get_logger(this_device), 193230557Sjimharris SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 194230557Sjimharris "SCIC SDS Remote Device 0x%x io request 0x%x could not be completd on the port 0x%x failed with status %d.\n", 195230557Sjimharris this_device, the_request, this_device->owning_port, status 196230557Sjimharris )); 197230557Sjimharris } 198230557Sjimharris } 199230557Sjimharris 200230557Sjimharris return status; 201230557Sjimharris} 202230557Sjimharris 203230557Sjimharris/** 204230557Sjimharris * @brief This is frame handler for smp device ready cmd substate. 205230557Sjimharris * 206230557Sjimharris * @param[in] this_device This is the device object that is receiving the frame. 207230557Sjimharris * @param[in] frame_index The index for the frame received. 208230557Sjimharris * 209230557Sjimharris * @return SCI_STATUS 210230557Sjimharris */ 211230557Sjimharrisstatic 212230557SjimharrisSCI_STATUS scic_sds_smp_remote_device_ready_cmd_substate_frame_handler( 213230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device, 214230557Sjimharris U32 frame_index 215230557Sjimharris) 216230557Sjimharris{ 217230557Sjimharris SCI_STATUS status; 218230557Sjimharris 219230557Sjimharris /// The device does not process any UF received from the hardware while 220230557Sjimharris /// in this state. All unsolicited frames are forwarded to the io request 221230557Sjimharris /// object. 222230557Sjimharris status = scic_sds_io_request_frame_handler( 223230557Sjimharris this_device->working_request, 224230557Sjimharris frame_index 225230557Sjimharris ); 226230557Sjimharris 227230557Sjimharris return status; 228230557Sjimharris} 229230557Sjimharris 230230557Sjimharris// --------------------------------------------------------------------------- 231230557Sjimharris 232230557SjimharrisSCIC_SDS_REMOTE_DEVICE_STATE_HANDLER_T 233230557Sjimharris scic_sds_smp_remote_device_ready_substate_handler_table[ 234230557Sjimharris SCIC_SDS_SMP_REMOTE_DEVICE_READY_MAX_SUBSTATES] = 235230557Sjimharris{ 236230557Sjimharris // SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE 237230557Sjimharris { 238230557Sjimharris { 239230557Sjimharris scic_sds_remote_device_default_start_handler, 240230557Sjimharris scic_sds_remote_device_ready_state_stop_handler, 241230557Sjimharris scic_sds_remote_device_default_fail_handler, 242230557Sjimharris scic_sds_remote_device_default_destruct_handler, 243230557Sjimharris scic_sds_remote_device_default_reset_handler, 244230557Sjimharris scic_sds_remote_device_default_reset_complete_handler, 245230557Sjimharris scic_sds_smp_remote_device_ready_idle_substate_start_io_handler, 246230557Sjimharris scic_sds_remote_device_default_complete_request_handler, 247230557Sjimharris scic_sds_remote_device_default_continue_request_handler, 248230557Sjimharris scic_sds_remote_device_default_start_request_handler, 249230557Sjimharris scic_sds_remote_device_default_complete_request_handler 250230557Sjimharris }, 251230557Sjimharris scic_sds_remote_device_default_suspend_handler, 252230557Sjimharris scic_sds_remote_device_default_resume_handler, 253230557Sjimharris scic_sds_remote_device_general_event_handler, 254230557Sjimharris scic_sds_remote_device_default_frame_handler 255230557Sjimharris }, 256230557Sjimharris // SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD 257230557Sjimharris { 258230557Sjimharris { 259230557Sjimharris scic_sds_remote_device_default_start_handler, 260230557Sjimharris scic_sds_remote_device_ready_state_stop_handler, 261230557Sjimharris scic_sds_remote_device_default_fail_handler, 262230557Sjimharris scic_sds_remote_device_default_destruct_handler, 263230557Sjimharris scic_sds_remote_device_default_reset_handler, 264230557Sjimharris scic_sds_remote_device_default_reset_complete_handler, 265230557Sjimharris scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler, 266230557Sjimharris scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler, 267230557Sjimharris scic_sds_remote_device_default_continue_request_handler, 268230557Sjimharris scic_sds_remote_device_default_start_request_handler, 269230557Sjimharris scic_sds_remote_device_default_complete_request_handler 270230557Sjimharris }, 271230557Sjimharris scic_sds_remote_device_default_suspend_handler, 272230557Sjimharris scic_sds_remote_device_default_resume_handler, 273230557Sjimharris scic_sds_remote_device_general_event_handler, 274230557Sjimharris scic_sds_smp_remote_device_ready_cmd_substate_frame_handler 275230557Sjimharris } 276230557Sjimharris}; 277230557Sjimharris 278230557Sjimharris/** 279230557Sjimharris * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE enter method. This 280230557Sjimharris * method sets the ready cmd substate handlers and reports the device as ready. 281230557Sjimharris * 282230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast into a 283230557Sjimharris * SCIC_SDS_REMOTE_DEVICE. 284230557Sjimharris * 285230557Sjimharris * @return none 286230557Sjimharris */ 287230557Sjimharrisstatic 288230557Sjimharrisvoid scic_sds_smp_remote_device_ready_idle_substate_enter( 289230557Sjimharris SCI_BASE_OBJECT_T *object 290230557Sjimharris) 291230557Sjimharris{ 292230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 293230557Sjimharris 294230557Sjimharris SET_STATE_HANDLER( 295230557Sjimharris this_device, 296230557Sjimharris scic_sds_smp_remote_device_ready_substate_handler_table, 297230557Sjimharris SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE 298230557Sjimharris ); 299230557Sjimharris 300230557Sjimharris scic_cb_remote_device_ready( 301230557Sjimharris scic_sds_remote_device_get_controller(this_device), this_device); 302230557Sjimharris} 303230557Sjimharris 304230557Sjimharris/** 305230557Sjimharris * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD enter method. This 306230557Sjimharris * method sets the remote device objects ready cmd substate handlers, and notify 307230557Sjimharris * core user that the device is not ready. 308230557Sjimharris * 309230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast into a 310230557Sjimharris * SCIC_SDS_REMOTE_DEVICE. 311230557Sjimharris * 312230557Sjimharris * @return none 313230557Sjimharris */ 314230557Sjimharrisstatic 315230557Sjimharrisvoid scic_sds_smp_remote_device_ready_cmd_substate_enter( 316230557Sjimharris SCI_BASE_OBJECT_T *object 317230557Sjimharris) 318230557Sjimharris{ 319230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 320230557Sjimharris 321230557Sjimharris ASSERT(this_device->working_request != NULL); 322230557Sjimharris 323230557Sjimharris SET_STATE_HANDLER( 324230557Sjimharris this_device, 325230557Sjimharris scic_sds_smp_remote_device_ready_substate_handler_table, 326230557Sjimharris SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD 327230557Sjimharris ); 328230557Sjimharris 329230557Sjimharris scic_cb_remote_device_not_ready( 330230557Sjimharris scic_sds_remote_device_get_controller(this_device), 331230557Sjimharris this_device, 332230557Sjimharris SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED 333230557Sjimharris ); 334230557Sjimharris} 335230557Sjimharris 336230557Sjimharris/** 337230557Sjimharris * This is the SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_CMD exit method. 338230557Sjimharris * 339230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast into a 340230557Sjimharris * SCIC_SDS_REMOTE_DEVICE. 341230557Sjimharris * 342230557Sjimharris * @return none 343230557Sjimharris */ 344230557Sjimharrisstatic 345230557Sjimharrisvoid scic_sds_smp_remote_device_ready_cmd_substate_exit( 346230557Sjimharris SCI_BASE_OBJECT_T *object 347230557Sjimharris) 348230557Sjimharris{ 349230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 350230557Sjimharris 351230557Sjimharris this_device->working_request = NULL; 352230557Sjimharris} 353230557Sjimharris 354230557Sjimharris// --------------------------------------------------------------------------- 355230557Sjimharris 356230557SjimharrisSCI_BASE_STATE_T 357230557Sjimharris scic_sds_smp_remote_device_ready_substate_table[ 358230557Sjimharris SCIC_SDS_SMP_REMOTE_DEVICE_READY_MAX_SUBSTATES] = 359230557Sjimharris{ 360230557Sjimharris { 361230557Sjimharris SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE, 362230557Sjimharris scic_sds_smp_remote_device_ready_idle_substate_enter, 363230557Sjimharris NULL 364230557Sjimharris }, 365230557Sjimharris { 366230557Sjimharris SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD, 367230557Sjimharris scic_sds_smp_remote_device_ready_cmd_substate_enter, 368230557Sjimharris scic_sds_smp_remote_device_ready_cmd_substate_exit 369230557Sjimharris } 370230557Sjimharris}; 371230557Sjimharris 372