1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0 3 * 4 * This file is provided under a dual BSD/GPLv2 license. When using or 5 * redistributing this file, you may do so under either license. 6 * 7 * GPL LICENSE SUMMARY 8 * 9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of version 2 of the GNU General Public License as 13 * published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 23 * The full GNU General Public License is included in this distribution 24 * in the file called LICENSE.GPL. 25 * 26 * BSD LICENSE 27 * 28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 34 * 35 * * Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * * Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in 39 * the documentation and/or other materials provided with the 40 * distribution. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 */ 54 #ifndef _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ 55 #define _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ 56 57 /** 58 * @file 59 * 60 * @brief This file contains the structures, constants, and prototypes 61 * associated with the remote node context in the silicon. It 62 * exists to model and manage the remote node context in the silicon. 63 */ 64 65 #ifdef __cplusplus 66 extern "C" { 67 #endif // __cplusplus 68 69 #include <dev/isci/scil/sci_types.h> 70 #include <dev/isci/scil/sci_base_state.h> 71 #include <dev/isci/scil/sci_base_state_machine.h> 72 #include <dev/isci/scil/sci_base_state_machine_logger.h> 73 74 // --------------------------------------------------------------------------- 75 76 /** 77 * This constant represents an invalid remote device id, it is used to program 78 * the STPDARNI register so the driver knows when it has received a SIGNATURE 79 * FIS from the SCU. 80 */ 81 #define SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX 0x0FFF 82 83 #define SCU_HARDWARE_SUSPENSION (0) 84 #define SCI_SOFTWARE_SUSPENSION (1) 85 86 struct SCIC_SDS_REQUEST; 87 struct SCIC_SDS_REMOTE_DEVICE; 88 struct SCIC_SDS_REMOTE_NODE_CONTEXT; 89 90 typedef void (*SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK)(void *); 91 92 typedef SCI_STATUS (*SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION)( 93 struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 94 SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 95 void * callback_parameter 96 ); 97 98 typedef SCI_STATUS (*SCIC_SDS_REMOTE_NODE_CONTEXT_SUSPEND_OPERATION)( 99 struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 100 U32 suspension_type, 101 SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback, 102 void * callback_parameter 103 ); 104 105 typedef SCI_STATUS (* SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST)( 106 struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 107 struct SCIC_SDS_REQUEST * the_request 108 ); 109 110 typedef SCI_STATUS (*SCIC_SDS_REMOTE_NODE_CONTEXT_EVENT_HANDLER)( 111 struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc, 112 U32 event_code 113 ); 114 115 // --------------------------------------------------------------------------- 116 117 typedef struct _SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS 118 { 119 /** 120 * This handle is invoked to stop the RNC. The callback is invoked when after 121 * the hardware notification that the RNC has been invalidated. 122 */ 123 SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION destruct_handler; 124 125 /** 126 * This handler is invoked when there is a request to suspend the RNC. The 127 * callback is invoked after the hardware notification that the remote node is 128 * suspended. 129 */ 130 SCIC_SDS_REMOTE_NODE_CONTEXT_SUSPEND_OPERATION suspend_handler; 131 132 /** 133 * This handler is invoked when there is a request to resume the RNC. The 134 * callback is invoked when after the RNC has reached the ready state. 135 */ 136 SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION resume_handler; 137 138 /** 139 * This handler is invoked when there is a request to start an io request 140 * operation. 141 */ 142 SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST start_io_handler; 143 144 /** 145 * This handler is invoked when there is a request to start a task request 146 * operation. 147 */ 148 SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST start_task_handler; 149 150 /** 151 * This handler is invoked where there is an RNC event that must be processed. 152 */ 153 SCIC_SDS_REMOTE_NODE_CONTEXT_EVENT_HANDLER event_handler; 154 155 } SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS; 156 157 // --------------------------------------------------------------------------- 158 159 /** 160 * @enum 161 * 162 * This is the enumeration of the remote node context states. 163 */ 164 typedef enum _SCIS_SDS_REMOTE_NODE_CONTEXT_STATES 165 { 166 /** 167 * This state is the initial state for a remote node context. On a resume 168 * request the remote node context will transition to the posting state. 169 */ 170 SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE, 171 172 /** 173 * This is a transition state that posts the RNi to the hardware. Once the RNC 174 * is posted the remote node context will be made ready. 175 */ 176 SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE, 177 178 /** 179 * This is a transition state that will post an RNC invalidate to the 180 * hardware. Once the invalidate is complete the remote node context will 181 * transition to the posting state. 182 */ 183 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE, 184 185 /** 186 * This is a transition state that will post an RNC resume to the hardare. 187 * Once the event notification of resume complete is received the remote node 188 * context will transition to the ready state. 189 */ 190 SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE, 191 192 /** 193 * This is the state that the remote node context must be in to accept io 194 * request operations. 195 */ 196 SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE, 197 198 /** 199 * This is the state that the remote node context transitions to when it gets 200 * a TX suspend notification from the hardware. 201 */ 202 SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE, 203 204 /** 205 * This is the state that the remote node context transitions to when it gets 206 * a TX RX suspend notification from the hardware. 207 */ 208 SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE, 209 210 /** 211 * This state is a wait state for the remote node context that waits for a 212 * suspend notification from the hardware. This state is entered when either 213 * there is a request to supend the remote node context or when there is a TC 214 * completion where the remote node will be suspended by the hardware. 215 */ 216 SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE, 217 218 SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES 219 220 } SCIS_SDS_REMOTE_NODE_CONTEXT_STATES; 221 222 /** 223 * @enum 224 * 225 * This enumeration is used to define the end destination state for the remote 226 * node context. 227 */ 228 enum SCIC_SDS_REMOTE_NODE_CONTEXT_DESTINATION_STATE 229 { 230 SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED, 231 SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY, 232 SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL 233 }; 234 235 /** 236 * @struct SCIC_SDS_REMOTE_NODE_CONTEXT 237 * 238 * @brief This structure contains the data associated with the remote 239 * node context object. The remote node context (RNC) object models 240 * the remote device information necessary to manage the 241 * silicon RNC. 242 */ 243 typedef struct SCIC_SDS_REMOTE_NODE_CONTEXT 244 { 245 /** 246 * This contains the information used to maintain the loggers for the base 247 * state machine. 248 */ 249 SCI_BASE_OBJECT_T parent; 250 251 /** 252 * This pointer simply points to the remote device object containing 253 * this RNC. 254 * 255 * @todo Consider making the device pointer the associated object of the 256 * the parent object. 257 */ 258 struct SCIC_SDS_REMOTE_DEVICE * device; 259 260 /** 261 * This field indicates the remote node index (RNI) associated with 262 * this RNC. 263 */ 264 U16 remote_node_index; 265 266 /** 267 * This field is the recorded suspension code or the reason for the remote node 268 * context suspension. 269 */ 270 U32 suspension_code; 271 272 /** 273 * This field is TRUE if the remote node context is resuming from its current 274 * state. This can cause an automatic resume on receiving a suspension 275 * notification. 276 */ 277 enum SCIC_SDS_REMOTE_NODE_CONTEXT_DESTINATION_STATE destination_state; 278 279 /** 280 * This field contains the callback function that the user requested to be 281 * called when the requested state transition is complete. 282 */ 283 SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK user_callback; 284 285 /** 286 * This field contains the parameter that is called when the user requested 287 * state transition is completed. 288 */ 289 void * user_cookie; 290 291 /** 292 * This field contains the data for the object's state machine. 293 */ 294 SCI_BASE_STATE_MACHINE_T state_machine; 295 296 SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS * state_handlers; 297 298 #ifdef SCI_LOGGING 299 /** 300 * This field conatins the ready substate machine logger. The logger will 301 * emit a message each time the ready substate machine changes state. 302 */ 303 SCI_BASE_STATE_MACHINE_LOGGER_T state_machine_logger; 304 #endif 305 306 } SCIC_SDS_REMOTE_NODE_CONTEXT_T; 307 308 // --------------------------------------------------------------------------- 309 310 extern SCI_BASE_STATE_T 311 scic_sds_remote_node_context_state_table[ 312 SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES]; 313 314 extern SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS 315 scic_sds_remote_node_context_state_handler_table[ 316 SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES]; 317 318 // --------------------------------------------------------------------------- 319 320 void scic_sds_remote_node_context_construct( 321 struct SCIC_SDS_REMOTE_DEVICE * device, 322 SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc, 323 U16 remote_node_index 324 ); 325 326 void scic_sds_remote_node_context_construct_buffer( 327 SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc 328 ); 329 330 BOOL scic_sds_remote_node_context_is_initialized( 331 SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc 332 ); 333 334 BOOL scic_sds_remote_node_context_is_ready( 335 SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc 336 ); 337 338 #define scic_sds_remote_node_context_set_remote_node_index(rnc, rni) \ 339 ((rnc)->remote_node_index = (rni)) 340 341 #define scic_sds_remote_node_context_get_remote_node_index(rcn) \ 342 ((rnc)->remote_node_index) 343 344 #define scic_sds_remote_node_context_event_handler(rnc, event_code) \ 345 ((rnc)->state_handlers->event_handler(rnc, event_code)) 346 347 #define scic_sds_remote_node_context_resume(rnc, callback, parameter) \ 348 ((rnc)->state_handlers->resume_handler(rnc, callback, parameter)) 349 350 #define scic_sds_remote_node_context_suspend(rnc, suspend_type, callback, parameter) \ 351 ((rnc)->state_handlers->suspend_handler(rnc, suspend_type, callback, parameter)) 352 353 #define scic_sds_remote_node_context_destruct(rnc, callback, parameter) \ 354 ((rnc)->state_handlers->destruct_handler(rnc, callback, parameter)) 355 356 #define scic_sds_remote_node_context_start_io(rnc, request) \ 357 ((rnc)->state_handlers->start_io_handler(rnc, request)) 358 359 #define scic_sds_remote_node_context_start_task(rnc, task) \ 360 ((rnc)->state_handlers->start_task_handler(rnc, task)) 361 362 // --------------------------------------------------------------------------- 363 364 #ifdef SCI_LOGGING 365 void scic_sds_remote_node_context_initialize_state_logging( 366 SCIC_SDS_REMOTE_NODE_CONTEXT_T *this_rnc 367 ); 368 369 void scic_sds_remote_node_context_deinitialize_state_logging( 370 SCIC_SDS_REMOTE_NODE_CONTEXT_T *this_rnc 371 ); 372 #else // SCI_LOGGING 373 #define scic_sds_remote_node_context_initialize_state_logging(x) 374 #define scic_sds_remote_node_context_deinitialize_state_logging(x) 375 #endif // SCI_LOGGING 376 377 #ifdef __cplusplus 378 } 379 #endif // __cplusplus 380 381 #endif // _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ 382 383