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