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 * $FreeBSD$ 55 */ 56 #ifndef _SCIF_SAS_REMOTE_DEVICE_H_ 57 #define _SCIF_SAS_REMOTE_DEVICE_H_ 58 59 /** 60 * @file 61 * 62 * @brief This file contains the protected interface structures, constants, 63 * and methods for the SCIF_SAS_REMOTE_DEVICE object. 64 */ 65 66 #ifdef __cplusplus 67 extern "C" { 68 #endif // __cplusplus 69 70 #include <dev/isci/scil/scif_remote_device.h> 71 72 #include <dev/isci/scil/sci_base_remote_device.h> 73 #include <dev/isci/scil/sci_base_request.h> 74 #include <dev/isci/scil/sci_base_state_machine_logger.h> 75 #include <dev/isci/scil/scif_sas_stp_remote_device.h> 76 #include <dev/isci/scil/scif_sas_smp_remote_device.h> 77 78 79 struct SCIF_SAS_DOMAIN; 80 struct SCIF_SAS_REMOTE_DEVICE; 81 struct SCIF_SAS_REQUEST; 82 83 /** 84 * This constant indicates the number of milliseconds to wait for the core 85 * to start/stop it's remote device object. 86 */ 87 #define SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT 1000 88 89 /** 90 * @enum _SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATES 91 * 92 * @brief This enumeration depicts all the substates for the remote device's 93 * starting substate machine. 94 */ 95 typedef enum _SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATES 96 { 97 /** 98 * This state indicates that the framework is waiting for the core to 99 * issue a scic_cb_remote_device_start_complete() notification. 100 */ 101 SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_AWAIT_COMPLETE, 102 103 /** 104 * This state indicates that the core has received the core's 105 * scic_cb_remote_device_start_complete() notification. 106 */ 107 SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_AWAIT_READY, 108 109 SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_MAX_STATES 110 111 } SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATES; 112 113 /** 114 * @enum _SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATES 115 * 116 * @brief This enumeration depicts all of the substates for the remote 117 * device READY substate machine. 118 */ 119 typedef enum _SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATES 120 { 121 /** 122 * The Operational sub-state indicates that the remote device object 123 * is capable of receiving and handling all request types. 124 */ 125 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL, 126 127 /** 128 * This substate indicates that core remote device is not ready. 129 * As a result, no new IO or Task Management requests are allowed. 130 */ 131 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED, 132 133 /** 134 * This substate indicates that task management to this device is 135 * ongoing and new IO requests are not allowed. 136 */ 137 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT, 138 139 /** 140 * This substate indicates that core remote device is not ready due 141 * to an NCQ error. As a result, no new IO requests are allowed. 142 */ 143 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR, 144 145 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_MAX_STATES 146 147 } SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATES; 148 149 struct SCIF_SAS_REMOTE_DEVICE; 150 typedef void (*SCIF_SAS_REMOTE_DEVICE_COMPLETION_HANDLER_T)( 151 struct SCIF_SAS_REMOTE_DEVICE *, 152 SCI_STATUS 153 ); 154 155 typedef void (*SCIF_SAS_REMOTE_DEVICE_HANDLER_T)( 156 struct SCIF_SAS_REMOTE_DEVICE * 157 ); 158 159 typedef void (*SCIF_SAS_REMOTE_DEVICE_NOT_READY_HANDLER_T)( 160 struct SCIF_SAS_REMOTE_DEVICE *, 161 U32 162 ); 163 164 /** 165 * @struct SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER 166 * 167 * @brief This structure defines the state handler methods for states and 168 * substates applicable for the framework remote device object. 169 */ 170 typedef struct SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER 171 { 172 SCI_BASE_REMOTE_DEVICE_STATE_HANDLER_T parent; 173 SCIF_SAS_REMOTE_DEVICE_COMPLETION_HANDLER_T start_complete_handler; 174 SCIF_SAS_REMOTE_DEVICE_COMPLETION_HANDLER_T stop_complete_handler; 175 SCIF_SAS_REMOTE_DEVICE_HANDLER_T ready_handler; 176 SCIF_SAS_REMOTE_DEVICE_NOT_READY_HANDLER_T not_ready_handler; 177 SCI_BASE_REMOTE_DEVICE_REQUEST_HANDLER_T start_high_priority_io_handler; 178 SCI_BASE_REMOTE_DEVICE_HIGH_PRIORITY_REQUEST_COMPLETE_HANDLER_T complete_high_priority_io_handler; 179 } SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T; 180 181 /** 182 * @struct SCIF_SAS_REMOTE_DEVICE 183 * 184 * @brief The SCI SAS Framework remote device object abstracts the SAS remote 185 * device level behavior for the framework component. Additionally, 186 * it provides a higher level of abstraction for the core remote 187 * device object. 188 */ 189 typedef struct SCIF_SAS_REMOTE_DEVICE 190 { 191 /** 192 * The SCI_BASE_REMOTE_DEVICE is the parent object for the 193 * SCIF_SAS_REMOTE_DEVICE object. 194 */ 195 SCI_BASE_REMOTE_DEVICE_T parent; 196 197 /** 198 * This field contains the handle for the SCI Core remote device object 199 * that is managed by this framework controller. 200 */ 201 SCI_REMOTE_DEVICE_HANDLE_T core_object; 202 203 /** 204 * This field references the list of state specific handler methods to 205 * be utilized for this remote device instance. 206 */ 207 SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T * state_handlers; 208 209 /** 210 * This field specifies the state machine utilized to manage the 211 * starting remote device substate machine. 212 */ 213 SCI_BASE_STATE_MACHINE_T starting_substate_machine; 214 215 /** 216 * This field specifies the state machine utilized to manage the 217 * starting remote device substate machine. 218 */ 219 SCI_BASE_STATE_MACHINE_T ready_substate_machine; 220 221 union 222 { 223 /** 224 * This field specifies the information specific to SATA/STP device 225 * instances. This field is not utilized for SSP/SMP. 226 */ 227 SCIF_SAS_STP_REMOTE_DEVICE_T stp_device; 228 229 /** 230 * This field specifies the information specific to SMP device instances. 231 * This field is not utilized for SSP/SATA/STP. 232 */ 233 SCIF_SAS_SMP_REMOTE_DEVICE_T smp_device; 234 235 }protocol_device; 236 237 /** 238 * This field indicates the domain object containing this remote device. 239 */ 240 struct SCIF_SAS_DOMAIN * domain; 241 242 /** 243 * This field counts the number of requests (IO and task management) 244 * that are currently outstanding for this device. 245 */ 246 U32 request_count; 247 248 /** 249 * This field counts the number of only task management request that are 250 * currently outstanding for this device. 251 */ 252 U32 task_request_count; 253 254 /** 255 * This field is utilize to store the status value of various operations 256 * the can be executed on this remote device instance. 257 */ 258 SCI_STATUS operation_status; 259 260 /** 261 * This field is utilize to indicate that the remote device should be 262 * destructed when it finally reaches the stopped state. This will 263 * include destructing the core remote device as well. 264 */ 265 BOOL destruct_when_stopped; 266 267 /** 268 * This field marks a device state of being discovered or not, majorly used 269 * during re-discover procedure. 270 */ 271 BOOL is_currently_discovered; 272 273 /** 274 * This filed stores the expander device this device connected to, only if this 275 * device is behind expander. So this field also served as a flag to tell if a 276 * device is a EA one. 277 */ 278 struct SCIF_SAS_REMOTE_DEVICE * containing_device; 279 280 /** 281 * This field stores the expander phy identifier for an expander attached 282 * device. This field is only used by expander attached device. 283 */ 284 U8 expander_phy_identifier; 285 286 /** 287 * This field stores the port width for a device. Most devices are narrow port 288 * device, their port width is 1. If a device is a wide port device, their 289 * port width is larger than 1. 290 */ 291 U8 device_port_width; 292 293 /** 294 * This field stores the destination state for a remote device in UPDATING 295 * PORT WIDTH state. The possible destination states for a remote device in 296 * UPDATING_PORT_WIDTH state are READY or STOPPING. 297 */ 298 U16 destination_state; 299 300 /** 301 * This field stores the scheduled/delayed EA target reset request. 302 */ 303 struct SCIF_SAS_REQUEST * ea_target_reset_request_scheduled; 304 305 #ifdef SCI_LOGGING 306 /** 307 * This field is the observer of the base state machine for this device 308 * object. 309 */ 310 SCI_BASE_OBSERVER_T base_state_machine_observer; 311 312 /** 313 * This field is the state machine logger of the startig substate machine for 314 * this device object. 315 */ 316 SCI_BASE_STATE_MACHINE_LOGGER_T starting_substate_machine_logger; 317 318 /** 319 * This field is the state machine logger of the ready substate machine for 320 * this device object. 321 */ 322 SCI_BASE_STATE_MACHINE_LOGGER_T ready_substate_machine_logger; 323 #endif // SCI_LOGGING 324 325 } SCIF_SAS_REMOTE_DEVICE_T; 326 327 extern SCI_BASE_STATE_T scif_sas_remote_device_state_table[]; 328 extern SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T 329 scif_sas_remote_device_state_handler_table[]; 330 331 extern SCI_BASE_STATE_T scif_sas_remote_device_starting_substate_table[]; 332 extern SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T 333 scif_sas_remote_device_starting_substate_handler_table[]; 334 335 extern SCI_BASE_STATE_T scif_sas_remote_device_ready_substate_table[]; 336 extern SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T 337 scif_sas_remote_device_ready_substate_handler_table[]; 338 339 /** 340 * @enum 341 * 342 * This enumeration is used to define the end destination state for the 343 * framework remote device. 344 */ 345 enum SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE 346 { 347 SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_UNSPECIFIED, 348 SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_READY, 349 SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING, 350 SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_UPDATING_PORT_WIDTH 351 }; 352 353 //****************************************************************************** 354 //* P R O T E C T E D M E T H O D S 355 //****************************************************************************** 356 void scif_sas_remote_device_save_report_phy_sata_information( 357 SMP_RESPONSE_REPORT_PHY_SATA_T * report_phy_sata_response 358 ); 359 360 void scif_sas_remote_device_target_reset( 361 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 362 struct SCIF_SAS_REQUEST * fw_request 363 ); 364 365 void scif_sas_remote_device_target_reset_complete( 366 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 367 struct SCIF_SAS_REQUEST * fw_request, 368 SCI_STATUS completion_status 369 ); 370 371 #ifdef SCI_LOGGING 372 void scif_sas_remote_device_initialize_state_logging( 373 SCIF_SAS_REMOTE_DEVICE_T * remote_device 374 ); 375 376 void scif_sas_remote_device_deinitialize_state_logging( 377 SCIF_SAS_REMOTE_DEVICE_T * remote_device 378 ); 379 #else // SCI_LOGGING 380 #define scif_sas_remote_device_initialize_state_logging(x) 381 #define scif_sas_remote_device_deinitialize_state_logging(x) 382 #endif // SCI_LOGGING 383 384 //****************************************************************************** 385 //* R E A D Y O P E R A T I O N A L S T A T E H A N D L E R S 386 //****************************************************************************** 387 388 SCI_STATUS scif_sas_remote_device_ready_operational_complete_io_handler( 389 SCI_BASE_REMOTE_DEVICE_T * remote_device, 390 SCI_BASE_REQUEST_T * io_request 391 ); 392 393 SCI_STATUS scif_sas_remote_device_ready_operational_complete_task_handler( 394 SCI_BASE_REMOTE_DEVICE_T * remote_device, 395 SCI_BASE_REQUEST_T * task_request 396 ); 397 398 SCI_STATUS scif_sas_remote_device_ready_task_management_complete_task_handler( 399 SCI_BASE_REMOTE_DEVICE_T * remote_device, 400 SCI_BASE_REQUEST_T * task_request 401 ); 402 403 //****************************************************************************** 404 //* D E F A U L T S T A T E H A N D L E R S 405 //****************************************************************************** 406 407 SCI_STATUS scif_sas_remote_device_default_start_handler( 408 SCI_BASE_REMOTE_DEVICE_T * remote_device 409 ); 410 411 SCI_STATUS scif_sas_remote_device_default_stop_handler( 412 SCI_BASE_REMOTE_DEVICE_T * remote_device 413 ); 414 415 SCI_STATUS scif_sas_remote_device_default_reset_handler( 416 SCI_BASE_REMOTE_DEVICE_T * remote_device 417 ); 418 419 SCI_STATUS scif_sas_remote_device_default_reset_complete_handler( 420 SCI_BASE_REMOTE_DEVICE_T * remote_device 421 ); 422 423 SCI_STATUS scif_sas_remote_device_default_start_io_handler( 424 SCI_BASE_REMOTE_DEVICE_T * remote_device, 425 SCI_BASE_REQUEST_T * io_request 426 ); 427 428 void scif_sas_remote_device_default_start_complete_handler( 429 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 430 SCI_STATUS completion_status 431 ); 432 433 void scif_sas_remote_device_default_stop_complete_handler( 434 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 435 SCI_STATUS completion_status 436 ); 437 438 SCI_STATUS scif_sas_remote_device_default_destruct_handler( 439 SCI_BASE_REMOTE_DEVICE_T * remote_device 440 ); 441 442 SCI_STATUS scif_sas_remote_device_default_complete_io_handler( 443 SCI_BASE_REMOTE_DEVICE_T * remote_device, 444 SCI_BASE_REQUEST_T * io_request 445 ); 446 447 SCI_STATUS scif_sas_remote_device_default_complete_high_priority_io_handler( 448 SCI_BASE_REMOTE_DEVICE_T * remote_device, 449 SCI_BASE_REQUEST_T * io_request, 450 void * response_data, 451 SCI_IO_STATUS completion_status 452 ); 453 454 SCI_STATUS scif_sas_remote_device_default_continue_io_handler( 455 SCI_BASE_REMOTE_DEVICE_T * remote_device, 456 SCI_BASE_REQUEST_T * io_request 457 ); 458 459 SCI_STATUS scif_sas_remote_device_default_start_task_handler( 460 SCI_BASE_REMOTE_DEVICE_T * remote_device, 461 SCI_BASE_REQUEST_T * task_request 462 ); 463 464 SCI_STATUS scif_sas_remote_device_default_complete_task_handler( 465 SCI_BASE_REMOTE_DEVICE_T * remote_device, 466 SCI_BASE_REQUEST_T * task_request 467 ); 468 469 void scif_sas_remote_device_default_ready_handler( 470 SCIF_SAS_REMOTE_DEVICE_T * fw_device 471 ); 472 473 void scif_sas_remote_device_default_not_ready_handler( 474 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 475 U32 reason_code 476 ); 477 478 SCI_STATUS scif_sas_remote_device_ready_task_management_start_high_priority_io_handler( 479 SCI_BASE_REMOTE_DEVICE_T * remote_device, 480 SCI_BASE_REQUEST_T * io_request 481 ); 482 483 SCI_STATUS scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler( 484 SCI_BASE_REMOTE_DEVICE_T * remote_device, 485 SCI_BASE_REQUEST_T * io_request, 486 void * response_data, 487 SCI_IO_STATUS completion_status 488 ); 489 490 #if !defined(DISABLE_WIDE_PORTED_TARGETS) 491 SCI_STATUS scif_sas_remote_device_update_port_width( 492 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 493 U8 new_port_width 494 ); 495 #else // !defined(DISABLE_WIDE_PORTED_TARGETS) 496 #define scif_sas_remote_device_update_port_width(device) SCI_FAILURE 497 #endif //#if !defined(DISABLE_WIDE_PORTED_TARGETS) 498 499 #ifdef __cplusplus 500 } 501 #endif // __cplusplus 502 503 #endif // _SCIF_SAS_REMOTE_DEVICE_H_ 504 505