1 /*- 2 * This file is provided under a dual BSD/GPLv2 license. When using or 3 * redistributing this file, you may do so under either license. 4 * 5 * GPL LICENSE SUMMARY 6 * 7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of version 2 of the GNU General Public License as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21 * The full GNU General Public License is included in this distribution 22 * in the file called LICENSE.GPL. 23 * 24 * BSD LICENSE 25 * 26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27 * All rights reserved. 28 * 29 * Redistribution and use in source and binary forms, with or without 30 * modification, are permitted provided that the following conditions 31 * are met: 32 * 33 * * Redistributions of source code must retain the above copyright 34 * notice, this list of conditions and the following disclaimer. 35 * * Redistributions in binary form must reproduce the above copyright 36 * notice, this list of conditions and the following disclaimer in 37 * the documentation and/or other materials provided with the 38 * distribution. 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 * 52 * $FreeBSD$ 53 */ 54 #ifndef _SCIF_SAS_REMOTE_DEVICE_H_ 55 #define _SCIF_SAS_REMOTE_DEVICE_H_ 56 57 /** 58 * @file 59 * 60 * @brief This file contains the protected interface structures, constants, 61 * and methods for the SCIF_SAS_REMOTE_DEVICE object. 62 */ 63 64 #ifdef __cplusplus 65 extern "C" { 66 #endif // __cplusplus 67 68 #include <dev/isci/scil/scif_remote_device.h> 69 70 #include <dev/isci/scil/sci_base_remote_device.h> 71 #include <dev/isci/scil/sci_base_request.h> 72 #include <dev/isci/scil/sci_base_state_machine_logger.h> 73 #include <dev/isci/scil/scif_sas_stp_remote_device.h> 74 #include <dev/isci/scil/scif_sas_smp_remote_device.h> 75 76 77 struct SCIF_SAS_DOMAIN; 78 struct SCIF_SAS_REMOTE_DEVICE; 79 struct SCIF_SAS_REQUEST; 80 81 /** 82 * This constant indicates the number of milliseconds to wait for the core 83 * to start/stop it's remote device object. 84 */ 85 #define SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT 1000 86 87 /** 88 * @enum _SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATES 89 * 90 * @brief This enumeration depicts all the substates for the remote device's 91 * starting substate machine. 92 */ 93 typedef enum _SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATES 94 { 95 /** 96 * This state indicates that the framework is waiting for the core to 97 * issue a scic_cb_remote_device_start_complete() notification. 98 */ 99 SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_AWAIT_COMPLETE, 100 101 /** 102 * This state indicates that the core has received the core's 103 * scic_cb_remote_device_start_complete() notification. 104 */ 105 SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_AWAIT_READY, 106 107 SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_MAX_STATES 108 109 } SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATES; 110 111 /** 112 * @enum _SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATES 113 * 114 * @brief This enumeration depicts all of the substates for the remote 115 * device READY substate machine. 116 */ 117 typedef enum _SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATES 118 { 119 /** 120 * The Operational sub-state indicates that the remote device object 121 * is capable of receiving and handling all request types. 122 */ 123 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL, 124 125 /** 126 * This substate indicates that core remote device is not ready. 127 * As a result, no new IO or Task Management requests are allowed. 128 */ 129 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED, 130 131 /** 132 * This substate indicates that task management to this device is 133 * ongoing and new IO requests are not allowed. 134 */ 135 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT, 136 137 /** 138 * This substate indicates that core remote device is not ready due 139 * to an NCQ error. As a result, no new IO requests are allowed. 140 */ 141 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR, 142 143 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_MAX_STATES 144 145 } SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATES; 146 147 struct SCIF_SAS_REMOTE_DEVICE; 148 typedef void (*SCIF_SAS_REMOTE_DEVICE_COMPLETION_HANDLER_T)( 149 struct SCIF_SAS_REMOTE_DEVICE *, 150 SCI_STATUS 151 ); 152 153 typedef void (*SCIF_SAS_REMOTE_DEVICE_HANDLER_T)( 154 struct SCIF_SAS_REMOTE_DEVICE * 155 ); 156 157 typedef void (*SCIF_SAS_REMOTE_DEVICE_NOT_READY_HANDLER_T)( 158 struct SCIF_SAS_REMOTE_DEVICE *, 159 U32 160 ); 161 162 /** 163 * @struct SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER 164 * 165 * @brief This structure defines the state handler methods for states and 166 * substates applicable for the framework remote device object. 167 */ 168 typedef struct SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER 169 { 170 SCI_BASE_REMOTE_DEVICE_STATE_HANDLER_T parent; 171 SCIF_SAS_REMOTE_DEVICE_COMPLETION_HANDLER_T start_complete_handler; 172 SCIF_SAS_REMOTE_DEVICE_COMPLETION_HANDLER_T stop_complete_handler; 173 SCIF_SAS_REMOTE_DEVICE_HANDLER_T ready_handler; 174 SCIF_SAS_REMOTE_DEVICE_NOT_READY_HANDLER_T not_ready_handler; 175 SCI_BASE_REMOTE_DEVICE_REQUEST_HANDLER_T start_high_priority_io_handler; 176 SCI_BASE_REMOTE_DEVICE_HIGH_PRIORITY_REQUEST_COMPLETE_HANDLER_T complete_high_priority_io_handler; 177 } SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T; 178 179 /** 180 * @struct SCIF_SAS_REMOTE_DEVICE 181 * 182 * @brief The SCI SAS Framework remote device object abstracts the SAS remote 183 * device level behavior for the framework component. Additionally, 184 * it provides a higher level of abstraction for the core remote 185 * device object. 186 */ 187 typedef struct SCIF_SAS_REMOTE_DEVICE 188 { 189 /** 190 * The SCI_BASE_REMOTE_DEVICE is the parent object for the 191 * SCIF_SAS_REMOTE_DEVICE object. 192 */ 193 SCI_BASE_REMOTE_DEVICE_T parent; 194 195 /** 196 * This field contains the handle for the SCI Core remote device object 197 * that is managed by this framework controller. 198 */ 199 SCI_REMOTE_DEVICE_HANDLE_T core_object; 200 201 /** 202 * This field references the list of state specific handler methods to 203 * be utilized for this remote device instance. 204 */ 205 SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T * state_handlers; 206 207 /** 208 * This field specifies the state machine utilized to manage the 209 * starting remote device substate machine. 210 */ 211 SCI_BASE_STATE_MACHINE_T starting_substate_machine; 212 213 /** 214 * This field specifies the state machine utilized to manage the 215 * starting remote device substate machine. 216 */ 217 SCI_BASE_STATE_MACHINE_T ready_substate_machine; 218 219 union 220 { 221 /** 222 * This field specifies the information specific to SATA/STP device 223 * instances. This field is not utilized for SSP/SMP. 224 */ 225 SCIF_SAS_STP_REMOTE_DEVICE_T stp_device; 226 227 /** 228 * This field specifies the information specific to SMP device instances. 229 * This field is not utilized for SSP/SATA/STP. 230 */ 231 SCIF_SAS_SMP_REMOTE_DEVICE_T smp_device; 232 233 }protocol_device; 234 235 /** 236 * This field indicates the domain object containing this remote device. 237 */ 238 struct SCIF_SAS_DOMAIN * domain; 239 240 /** 241 * This field counts the number of requests (IO and task management) 242 * that are currently outstanding for this device. 243 */ 244 U32 request_count; 245 246 /** 247 * This field counts the number of only task management request that are 248 * currently outstanding for this device. 249 */ 250 U32 task_request_count; 251 252 /** 253 * This field is utilize to store the status value of various operations 254 * the can be executed on this remote device instance. 255 */ 256 SCI_STATUS operation_status; 257 258 /** 259 * This field is utilize to indicate that the remote device should be 260 * destructed when it finally reaches the stopped state. This will 261 * include destructing the core remote device as well. 262 */ 263 BOOL destruct_when_stopped; 264 265 /** 266 * This field marks a device state of being discovered or not, majorly used 267 * during re-discover procedure. 268 */ 269 BOOL is_currently_discovered; 270 271 /** 272 * This filed stores the expander device this device connected to, only if this 273 * device is behind expander. So this field also served as a flag to tell if a 274 * device is a EA one. 275 */ 276 struct SCIF_SAS_REMOTE_DEVICE * containing_device; 277 278 /** 279 * This field stores the expander phy identifier for an expander attached 280 * device. This field is only used by expander attached device. 281 */ 282 U8 expander_phy_identifier; 283 284 /** 285 * This field stores the port width for a device. Most devices are narrow port 286 * device, their port width is 1. If a device is a wide port device, their 287 * port width is larger than 1. 288 */ 289 U8 device_port_width; 290 291 /** 292 * This field stores the destination state for a remote device in UPDATING 293 * PORT WIDTH state. The possible destination states for a remote device in 294 * UPDATING_PORT_WIDTH state are READY or STOPPING. 295 */ 296 U16 destination_state; 297 298 /** 299 * This field stores the scheduled/delayed EA target reset request. 300 */ 301 struct SCIF_SAS_REQUEST * ea_target_reset_request_scheduled; 302 303 #ifdef SCI_LOGGING 304 /** 305 * This field is the observer of the base state machine for this device 306 * object. 307 */ 308 SCI_BASE_OBSERVER_T base_state_machine_observer; 309 310 /** 311 * This field is the state machine logger of the startig substate machine for 312 * this device object. 313 */ 314 SCI_BASE_STATE_MACHINE_LOGGER_T starting_substate_machine_logger; 315 316 /** 317 * This field is the state machine logger of the ready substate machine for 318 * this device object. 319 */ 320 SCI_BASE_STATE_MACHINE_LOGGER_T ready_substate_machine_logger; 321 #endif // SCI_LOGGING 322 323 } SCIF_SAS_REMOTE_DEVICE_T; 324 325 extern SCI_BASE_STATE_T scif_sas_remote_device_state_table[]; 326 extern SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T 327 scif_sas_remote_device_state_handler_table[]; 328 329 extern SCI_BASE_STATE_T scif_sas_remote_device_starting_substate_table[]; 330 extern SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T 331 scif_sas_remote_device_starting_substate_handler_table[]; 332 333 extern SCI_BASE_STATE_T scif_sas_remote_device_ready_substate_table[]; 334 extern SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T 335 scif_sas_remote_device_ready_substate_handler_table[]; 336 337 /** 338 * @enum 339 * 340 * This enumeration is used to define the end destination state for the 341 * framework remote device. 342 */ 343 enum SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE 344 { 345 SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_UNSPECIFIED, 346 SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_READY, 347 SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING, 348 SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_UPDATING_PORT_WIDTH 349 }; 350 351 //****************************************************************************** 352 //* P R O T E C T E D M E T H O D S 353 //****************************************************************************** 354 void scif_sas_remote_device_save_report_phy_sata_information( 355 SMP_RESPONSE_REPORT_PHY_SATA_T * report_phy_sata_response 356 ); 357 358 void scif_sas_remote_device_target_reset( 359 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 360 struct SCIF_SAS_REQUEST * fw_request 361 ); 362 363 void scif_sas_remote_device_target_reset_complete( 364 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 365 struct SCIF_SAS_REQUEST * fw_request, 366 SCI_STATUS completion_status 367 ); 368 369 #ifdef SCI_LOGGING 370 void scif_sas_remote_device_initialize_state_logging( 371 SCIF_SAS_REMOTE_DEVICE_T * remote_device 372 ); 373 374 void scif_sas_remote_device_deinitialize_state_logging( 375 SCIF_SAS_REMOTE_DEVICE_T * remote_device 376 ); 377 #else // SCI_LOGGING 378 #define scif_sas_remote_device_initialize_state_logging(x) 379 #define scif_sas_remote_device_deinitialize_state_logging(x) 380 #endif // SCI_LOGGING 381 382 //****************************************************************************** 383 //* 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 384 //****************************************************************************** 385 386 SCI_STATUS scif_sas_remote_device_ready_operational_complete_io_handler( 387 SCI_BASE_REMOTE_DEVICE_T * remote_device, 388 SCI_BASE_REQUEST_T * io_request 389 ); 390 391 SCI_STATUS scif_sas_remote_device_ready_operational_complete_task_handler( 392 SCI_BASE_REMOTE_DEVICE_T * remote_device, 393 SCI_BASE_REQUEST_T * task_request 394 ); 395 396 SCI_STATUS scif_sas_remote_device_ready_task_management_complete_task_handler( 397 SCI_BASE_REMOTE_DEVICE_T * remote_device, 398 SCI_BASE_REQUEST_T * task_request 399 ); 400 401 //****************************************************************************** 402 //* D E F A U L T S T A T E H A N D L E R S 403 //****************************************************************************** 404 405 SCI_STATUS scif_sas_remote_device_default_start_handler( 406 SCI_BASE_REMOTE_DEVICE_T * remote_device 407 ); 408 409 SCI_STATUS scif_sas_remote_device_default_stop_handler( 410 SCI_BASE_REMOTE_DEVICE_T * remote_device 411 ); 412 413 SCI_STATUS scif_sas_remote_device_default_reset_handler( 414 SCI_BASE_REMOTE_DEVICE_T * remote_device 415 ); 416 417 SCI_STATUS scif_sas_remote_device_default_reset_complete_handler( 418 SCI_BASE_REMOTE_DEVICE_T * remote_device 419 ); 420 421 SCI_STATUS scif_sas_remote_device_default_start_io_handler( 422 SCI_BASE_REMOTE_DEVICE_T * remote_device, 423 SCI_BASE_REQUEST_T * io_request 424 ); 425 426 void scif_sas_remote_device_default_start_complete_handler( 427 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 428 SCI_STATUS completion_status 429 ); 430 431 void scif_sas_remote_device_default_stop_complete_handler( 432 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 433 SCI_STATUS completion_status 434 ); 435 436 SCI_STATUS scif_sas_remote_device_default_destruct_handler( 437 SCI_BASE_REMOTE_DEVICE_T * remote_device 438 ); 439 440 SCI_STATUS scif_sas_remote_device_default_complete_io_handler( 441 SCI_BASE_REMOTE_DEVICE_T * remote_device, 442 SCI_BASE_REQUEST_T * io_request 443 ); 444 445 SCI_STATUS scif_sas_remote_device_default_complete_high_priority_io_handler( 446 SCI_BASE_REMOTE_DEVICE_T * remote_device, 447 SCI_BASE_REQUEST_T * io_request, 448 void * response_data, 449 SCI_IO_STATUS completion_status 450 ); 451 452 SCI_STATUS scif_sas_remote_device_default_continue_io_handler( 453 SCI_BASE_REMOTE_DEVICE_T * remote_device, 454 SCI_BASE_REQUEST_T * io_request 455 ); 456 457 SCI_STATUS scif_sas_remote_device_default_start_task_handler( 458 SCI_BASE_REMOTE_DEVICE_T * remote_device, 459 SCI_BASE_REQUEST_T * task_request 460 ); 461 462 SCI_STATUS scif_sas_remote_device_default_complete_task_handler( 463 SCI_BASE_REMOTE_DEVICE_T * remote_device, 464 SCI_BASE_REQUEST_T * task_request 465 ); 466 467 void scif_sas_remote_device_default_ready_handler( 468 SCIF_SAS_REMOTE_DEVICE_T * fw_device 469 ); 470 471 void scif_sas_remote_device_default_not_ready_handler( 472 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 473 U32 reason_code 474 ); 475 476 SCI_STATUS scif_sas_remote_device_ready_task_management_start_high_priority_io_handler( 477 SCI_BASE_REMOTE_DEVICE_T * remote_device, 478 SCI_BASE_REQUEST_T * io_request 479 ); 480 481 SCI_STATUS scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler( 482 SCI_BASE_REMOTE_DEVICE_T * remote_device, 483 SCI_BASE_REQUEST_T * io_request, 484 void * response_data, 485 SCI_IO_STATUS completion_status 486 ); 487 488 #if !defined(DISABLE_WIDE_PORTED_TARGETS) 489 SCI_STATUS scif_sas_remote_device_update_port_width( 490 SCIF_SAS_REMOTE_DEVICE_T * fw_device, 491 U8 new_port_width 492 ); 493 #else // !defined(DISABLE_WIDE_PORTED_TARGETS) 494 #define scif_sas_remote_device_update_port_width(device) SCI_FAILURE 495 #endif //#if !defined(DISABLE_WIDE_PORTED_TARGETS) 496 497 #ifdef __cplusplus 498 } 499 #endif // __cplusplus 500 501 #endif // _SCIF_SAS_REMOTE_DEVICE_H_ 502 503