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