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_IO_REQUEST_H_ 55 #define _SCIC_SDS_IO_REQUEST_H_ 56 57 /** 58 * @file 59 * 60 * @brief This file contains the structures, constants and prototypes for the 61 * SCIC_SDS_IO_REQUEST object. 62 */ 63 64 #ifdef __cplusplus 65 extern "C" { 66 #endif // __cplusplus 67 68 #include <sys/param.h> 69 70 #include <dev/isci/scil/scic_io_request.h> 71 72 #include <dev/isci/scil/sci_base_request.h> 73 #include <dev/isci/scil/sci_base_state_machine_logger.h> 74 #include <dev/isci/scil/scu_task_context.h> 75 #include <dev/isci/scil/intel_sas.h> 76 77 struct SCIC_SDS_CONTROLLER; 78 struct SCIC_SDS_REMOTE_DEVICE; 79 struct SCIC_SDS_IO_REQUEST_STATE_HANDLER; 80 81 /** 82 * @enum _SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATES 83 * 84 * @brief This enumeration depicts all of the substates for a task 85 * management request to be performed in the STARTED super-state. 86 */ 87 typedef enum _SCIC_SDS_RAW_REQUEST_STARTED_TASK_MGMT_SUBSTATES 88 { 89 /** 90 * The AWAIT_TC_COMPLETION sub-state indicates that the started raw 91 * task management request is waiting for the transmission of the 92 * initial frame (i.e. command, task, etc.). 93 */ 94 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION, 95 96 /** 97 * This sub-state indicates that the started task management request 98 * is waiting for the reception of an unsolicited frame 99 * (i.e. response IU). 100 */ 101 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE, 102 103 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_MAX_SUBSTATES 104 105 } SCIC_SDS_RAW_REQUEST_STARTED_TASK_MGMT_SUBSTATES; 106 107 108 /** 109 * @enum _SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATES 110 * 111 * @brief This enumeration depicts all of the substates for a SMP 112 * request to be performed in the STARTED super-state. 113 */ 114 typedef enum _SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATES 115 { 116 /** 117 * This sub-state indicates that the started task management request 118 * is waiting for the reception of an unsolicited frame 119 * (i.e. response IU). 120 */ 121 SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE, 122 123 /** 124 * The AWAIT_TC_COMPLETION sub-state indicates that the started SMP request is 125 * waiting for the transmission of the initial frame (i.e. command, task, etc.). 126 */ 127 SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION, 128 129 SCIC_SDS_SMP_REQUEST_STARTED_MAX_SUBSTATES 130 131 } SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATES; 132 133 /** 134 * @struct SCIC_SDS_IO_REQUEST 135 * 136 * @brief This structure contains or references all of the data necessary 137 * to process a task management or normal IO request. 138 */ 139 typedef struct SCIC_SDS_REQUEST 140 { 141 /** 142 * This field indictes the parent object of the request. 143 */ 144 SCI_BASE_REQUEST_T parent; 145 146 void *user_request; 147 148 /** 149 * This field simply points to the controller to which this IO request 150 * is associated. 151 */ 152 struct SCIC_SDS_CONTROLLER *owning_controller; 153 154 /** 155 * This field simply points to the remote device to which this IO request 156 * is associated. 157 */ 158 struct SCIC_SDS_REMOTE_DEVICE *target_device; 159 160 /** 161 * This field is utilized to determine if the SCI user is managing 162 * the IO tag for this request or if the core is managing it. 163 */ 164 BOOL was_tag_assigned_by_user; 165 166 /** 167 * This field indicates the IO tag for this request. The IO tag is 168 * comprised of the task_index and a sequence count. The sequence count 169 * is utilized to help identify tasks from one life to another. 170 */ 171 U16 io_tag; 172 173 /** 174 * This field specifies the sat protocol being utilized for this 175 * IO request, such as SAT_PROTOCOL_PIO_DATA_IN, SAT_PROTOCOL_FPDMA etc. 176 */ 177 U8 sat_protocol; 178 179 /** 180 * This field specifies the protocol being utilized for this 181 * IO request. 182 */ 183 SCIC_TRANSPORT_PROTOCOL protocol; 184 185 /** 186 * This field indicates the completion status taken from the SCUs 187 * completion code. It indicates the completion result for the SCU hardware. 188 */ 189 U32 scu_status; 190 191 /** 192 * This field indicates the completion status returned to the SCI user. It 193 * indicates the users view of the io request completion. 194 */ 195 U32 sci_status; 196 197 /** 198 * This field contains the value to be utilized when posting (e.g. Post_TC, 199 * Post_TC_Abort) this request to the silicon. 200 */ 201 U32 post_context; 202 203 void *command_buffer; 204 void *response_buffer; 205 SCU_TASK_CONTEXT_T *task_context_buffer; 206 SCU_SGL_ELEMENT_PAIR_T *sgl_element_pair_buffer; 207 208 /** 209 * This field indicates if this request is a task management request or 210 * normal IO request. 211 */ 212 BOOL is_task_management_request; 213 214 /** 215 * This field indicates that this request contains an initialized started 216 * substate machine. 217 */ 218 BOOL has_started_substate_machine; 219 220 /** 221 * This field is a pointer to the stored rx frame data. It is used in STP 222 * internal requests and SMP response frames. If this field is non-NULL the 223 * saved frame must be released on IO request completion. 224 * 225 * @todo In the future do we want to keep a list of RX frame buffers? 226 */ 227 U32 saved_rx_frame_index; 228 229 /** 230 * This field specifies the data necessary to manage the sub-state 231 * machine executed while in the SCI_BASE_REQUEST_STATE_STARTED state. 232 */ 233 SCI_BASE_STATE_MACHINE_T started_substate_machine; 234 235 /** 236 * This field specifies the current state handlers in place for this 237 * IO Request object. This field is updated each time the request 238 * changes state. 239 */ 240 struct SCIC_SDS_IO_REQUEST_STATE_HANDLER *state_handlers; 241 242 #ifdef SCI_LOGGING 243 /** 244 * This field is the observer of the started subsate machine 245 */ 246 SCI_BASE_STATE_MACHINE_LOGGER_T started_substate_machine_logger; 247 #endif 248 249 /** 250 * This field in the recorded device sequence for the io request. This is 251 * recorded during the build operation and is compared in the start 252 * operation. If the sequence is different then there was a change of 253 * devices from the build to start operations. 254 */ 255 U8 device_sequence; 256 257 } SCIC_SDS_REQUEST_T; 258 259 260 typedef SCI_STATUS (*SCIC_SDS_IO_REQUEST_FRAME_HANDLER_T)( 261 SCIC_SDS_REQUEST_T * this_request, 262 U32 frame_index); 263 264 typedef SCI_STATUS (*SCIC_SDS_IO_REQUEST_EVENT_HANDLER_T)( 265 SCIC_SDS_REQUEST_T * this_request, 266 U32 event_code); 267 268 typedef SCI_STATUS (*SCIC_SDS_IO_REQUEST_TASK_COMPLETION_HANDLER_T)( 269 SCIC_SDS_REQUEST_T * this_request, 270 U32 completion_code); 271 272 /** 273 * @struct SCIC_SDS_IO_REQUEST_STATE_HANDLER 274 * 275 * @brief This is the SDS core definition of the state handlers. 276 */ 277 typedef struct SCIC_SDS_IO_REQUEST_STATE_HANDLER 278 { 279 SCI_BASE_REQUEST_STATE_HANDLER_T parent; 280 281 SCIC_SDS_IO_REQUEST_TASK_COMPLETION_HANDLER_T tc_completion_handler; 282 SCIC_SDS_IO_REQUEST_EVENT_HANDLER_T event_handler; 283 SCIC_SDS_IO_REQUEST_FRAME_HANDLER_T frame_handler; 284 285 } SCIC_SDS_IO_REQUEST_STATE_HANDLER_T; 286 287 extern SCI_BASE_STATE_T scic_sds_request_state_table[]; 288 extern SCIC_SDS_IO_REQUEST_STATE_HANDLER_T 289 scic_sds_request_state_handler_table[]; 290 291 extern SCI_BASE_STATE_T scic_sds_io_request_started_task_mgmt_substate_table[]; 292 extern SCIC_SDS_IO_REQUEST_STATE_HANDLER_T 293 scic_sds_ssp_task_request_started_substate_handler_table[]; 294 295 extern SCI_BASE_STATE_T scic_sds_smp_request_started_substate_table[]; 296 extern SCIC_SDS_IO_REQUEST_STATE_HANDLER_T 297 scic_sds_smp_request_started_substate_handler_table[]; 298 299 /** 300 * This macro returns the maximum number of SGL element paris that we will 301 * support in a single IO request. 302 */ 303 #define SCU_MAX_SGL_ELEMENT_PAIRS ((SCU_IO_REQUEST_SGE_COUNT + 1) / 2) 304 305 /** 306 * This macro will return the controller for this io request object 307 */ 308 #define scic_sds_request_get_controller(this_request) \ 309 ((this_request)->owning_controller) 310 311 /** 312 * This macro will return the device for this io request object 313 */ 314 #define scic_sds_request_get_device(this_request) \ 315 ((this_request)->target_device) 316 317 /** 318 * This macro will return the port for this io request object 319 */ 320 #define scic_sds_request_get_port(this_request) \ 321 scic_sds_remote_device_get_port(scic_sds_request_get_device(this_request)) 322 323 /** 324 * This macro returns the constructed post context result for the io 325 * request. 326 */ 327 #define scic_sds_request_get_post_context(this_request) \ 328 ((this_request)->post_context) 329 330 /** 331 * This is a helper macro to return the os handle for this request object. 332 */ 333 #define scic_sds_request_get_task_context(request) \ 334 ((request)->task_context_buffer) 335 336 #define scic_sds_request_align_task_context_buffer(address) \ 337 ((SCU_TASK_CONTEXT_T *)( \ 338 (((POINTER_UINT)(address)) + (CACHE_LINE_SIZE - 1)) \ 339 & ~(CACHE_LINE_SIZE - 1) \ 340 )) 341 342 /** 343 * This macro will align the memory address so that it is correct for the SCU 344 * hardware to DMA the SGL element pairs. 345 */ 346 #define scic_sds_request_align_sgl_element_buffer(address) \ 347 ((SCU_SGL_ELEMENT_PAIR_T *)( \ 348 ((char *)(address)) \ 349 + ( \ 350 ((~(POINTER_UINT)(address)) + 1) \ 351 & (sizeof(SCU_SGL_ELEMENT_PAIR_T) - 1) \ 352 ) \ 353 )) 354 355 /** 356 * This macro will set the scu hardware status and sci request completion 357 * status for an io request. 358 */ 359 #define scic_sds_request_set_status(request, scu_status_code, sci_status_code) \ 360 { \ 361 (request)->scu_status = (scu_status_code); \ 362 (request)->sci_status = (sci_status_code); \ 363 } 364 365 #define scic_sds_request_complete(a_request) \ 366 ((a_request)->state_handlers->parent.complete_handler(&(a_request)->parent)) 367 368 U32 scic_sds_request_get_min_timer_count(void); 369 370 U32 scic_sds_request_get_max_timer_count(void); 371 372 373 /** 374 * This macro invokes the core state task completion handler for the 375 * SCIC_SDS_IO_REQUEST_T object. 376 */ 377 #define scic_sds_io_request_tc_completion(this_request, completion_code) \ 378 { \ 379 if (this_request->parent.state_machine.current_state_id \ 380 == SCI_BASE_REQUEST_STATE_STARTED \ 381 && this_request->has_started_substate_machine \ 382 == FALSE) \ 383 scic_sds_request_started_state_tc_completion_handler(this_request, completion_code); \ 384 else \ 385 this_request->state_handlers->tc_completion_handler(this_request, completion_code); \ 386 } 387 388 /** 389 * This macro zeros the hardware SGL element data 390 */ 391 #define SCU_SGL_ZERO(scu_sge) \ 392 { \ 393 (scu_sge).length = 0; \ 394 (scu_sge).address_lower = 0; \ 395 (scu_sge).address_upper = 0; \ 396 (scu_sge).address_modifier = 0; \ 397 } 398 399 /** 400 * This macro copys the SGL Element data from the host os to the hardware SGL 401 * elment data 402 */ 403 #define SCU_SGL_COPY(os_handle, scu_sge, os_sge) \ 404 { \ 405 (scu_sge).length = \ 406 scic_cb_sge_get_length_field(os_handle, os_sge); \ 407 (scu_sge).address_upper = \ 408 sci_cb_physical_address_upper(scic_cb_sge_get_address_field(os_handle, os_sge)); \ 409 (scu_sge).address_lower = \ 410 sci_cb_physical_address_lower(scic_cb_sge_get_address_field(os_handle, os_sge)); \ 411 (scu_sge).address_modifier = 0; \ 412 } 413 414 //***************************************************************************** 415 //* CORE REQUEST PROTOTYPES 416 //***************************************************************************** 417 418 SCU_SGL_ELEMENT_PAIR_T *scic_sds_request_get_sgl_element_pair( 419 SCIC_SDS_REQUEST_T *this_request, 420 U32 sgl_pair_index 421 ); 422 423 void scic_sds_request_build_sgl( 424 SCIC_SDS_REQUEST_T *this_request 425 ); 426 427 void scic_sds_ssp_io_request_assign_buffers( 428 SCIC_SDS_REQUEST_T *this_request 429 ); 430 431 void scic_sds_ssp_task_request_assign_buffers( 432 SCIC_SDS_REQUEST_T *this_request 433 ); 434 435 void scic_sds_stp_request_assign_buffers( 436 SCIC_SDS_REQUEST_T * this_request 437 ); 438 439 void scic_sds_smp_request_assign_buffers( 440 SCIC_SDS_REQUEST_T * this_request 441 ); 442 443 // --------------------------------------------------------------------------- 444 445 SCI_STATUS scic_sds_request_start( 446 SCIC_SDS_REQUEST_T *this_request 447 ); 448 449 SCI_STATUS scic_sds_io_request_terminate( 450 SCIC_SDS_REQUEST_T *this_request 451 ); 452 453 SCI_STATUS scic_sds_io_request_complete( 454 SCIC_SDS_REQUEST_T *this_request 455 ); 456 457 void scic_sds_io_request_copy_response( 458 SCIC_SDS_REQUEST_T *this_request 459 ); 460 461 SCI_STATUS scic_sds_io_request_event_handler( 462 SCIC_SDS_REQUEST_T *this_request, 463 U32 event_code 464 ); 465 466 SCI_STATUS scic_sds_io_request_frame_handler( 467 SCIC_SDS_REQUEST_T *this_request, 468 U32 frame_index 469 ); 470 471 SCI_STATUS scic_sds_task_request_complete( 472 SCIC_SDS_REQUEST_T *this_request 473 ); 474 475 SCI_STATUS scic_sds_task_request_terminate( 476 SCIC_SDS_REQUEST_T *this_request 477 ); 478 479 #ifdef SCI_LOGGING 480 void scic_sds_request_initialize_state_logging( 481 SCIC_SDS_REQUEST_T *this_request 482 ); 483 484 void scic_sds_request_deinitialize_state_logging( 485 SCIC_SDS_REQUEST_T *this_request 486 ); 487 #else // SCI_LOGGING 488 #define scic_sds_request_initialize_state_logging(x) 489 #define scic_sds_request_deinitialize_state_logging(x) 490 #endif // SCI_LOGGING 491 492 //***************************************************************************** 493 //* DEFAULT STATE HANDLERS 494 //***************************************************************************** 495 496 SCI_STATUS scic_sds_request_default_start_handler( 497 SCI_BASE_REQUEST_T *this_request 498 ); 499 500 SCI_STATUS scic_sds_request_default_abort_handler( 501 SCI_BASE_REQUEST_T *this_request 502 ); 503 504 SCI_STATUS scic_sds_request_default_complete_handler( 505 SCI_BASE_REQUEST_T *this_request 506 ); 507 508 SCI_STATUS scic_sds_request_default_destruct_handler( 509 SCI_BASE_REQUEST_T *this_request 510 ); 511 512 SCI_STATUS scic_sds_request_default_tc_completion_handler( 513 SCIC_SDS_REQUEST_T * this_request, 514 U32 completion_code 515 ); 516 517 SCI_STATUS scic_sds_request_default_event_handler( 518 SCIC_SDS_REQUEST_T * this_request, 519 U32 event_code 520 ); 521 522 SCI_STATUS scic_sds_request_default_frame_handler( 523 SCIC_SDS_REQUEST_T * this_request, 524 U32 frame_index 525 ); 526 527 //***************************************************************************** 528 //* STARTED STATE HANDLERS 529 //***************************************************************************** 530 531 SCI_STATUS scic_sds_request_started_state_abort_handler( 532 SCI_BASE_REQUEST_T *this_request 533 ); 534 535 SCI_STATUS scic_sds_request_started_state_tc_completion_handler( 536 SCIC_SDS_REQUEST_T * this_request, 537 U32 completion_code 538 ); 539 540 #ifdef __cplusplus 541 } 542 #endif // __cplusplus 543 544 #endif // _SCIC_SDS_IO_REQUEST_H_ 545