2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
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.
9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
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.
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.
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.
28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
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
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.
55 #include <sys/cdefs.h>
56 __FBSDID("$FreeBSD$");
58 #include <dev/isci/scil/intel_sat.h>
59 #include <dev/isci/scil/intel_sata.h>
60 #include <dev/isci/scil/sci_types.h>
61 #include <dev/isci/scil/scic_remote_device.h>
62 #include <dev/isci/scil/scic_user_callback.h>
63 #include <dev/isci/scil/scic_sds_controller.h>
64 #include <dev/isci/scil/scic_sds_remote_device.h>
65 #include <dev/isci/scil/scic_sds_stp_request.h>
66 #include <dev/isci/scil/scic_sds_stp_pio_request.h>
67 #include <dev/isci/scil/scic_sds_logger.h>
68 #include <dev/isci/sci_environment.h>
69 #include <dev/isci/scil/sci_base_state_machine.h>
70 #include <dev/isci/scil/scu_task_context.h>
71 #include <dev/isci/scil/intel_ata.h>
72 #include <dev/isci/scil/sci_util.h>
73 #include <dev/isci/scil/scic_sds_logger.h>
74 #include <dev/isci/scil/scic_sds_request.h>
75 #include <dev/isci/scil/scic_sds_stp_request.h>
76 #include <dev/isci/scil/scu_completion_codes.h>
77 #include <dev/isci/scil/scu_event_codes.h>
78 #include <dev/isci/scil/sci_base_state.h>
79 #include <dev/isci/scil/scic_sds_unsolicited_frame_control.h>
80 #include <dev/isci/scil/scic_io_request.h>
82 #if !defined(DISABLE_ATAPI)
83 #include <dev/isci/scil/scic_sds_stp_packet_request.h>
87 * This macro returns the address of the stp h2d reg fis buffer in the io
90 #define scic_sds_stp_request_get_h2d_reg_buffer_unaligned(memory) \
91 ((SATA_FIS_REG_H2D_T *)( \
92 ((char *)(memory)) + sizeof(SCIC_SDS_STP_REQUEST_T) \
96 * This macro aligns the stp command buffer in DWORD alignment
98 #define scic_sds_stp_request_align_h2d_reg_buffer(address) \
99 ((SATA_FIS_REG_H2D_T *)( \
100 (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \
101 & ~(sizeof(U32)- 1) \
105 * This macro returns the DWORD-aligned stp command buffer
107 #define scic_sds_stp_request_get_h2d_reg_buffer(memory) \
108 ((SATA_FIS_REG_H2D_T *) \
109 ((char *)scic_sds_stp_request_align_h2d_reg_buffer( \
110 (char *) scic_sds_stp_request_get_h2d_reg_buffer_unaligned(memory) \
114 * This macro returns the address of the stp response buffer in the io
117 #define scic_sds_stp_request_get_response_buffer_unaligned(memory) \
118 ((SATA_FIS_REG_D2H_T *)( \
119 ((char *)(scic_sds_stp_request_get_h2d_reg_buffer(memory))) \
120 + sizeof(SATA_FIS_REG_H2D_T) \
125 * This macro aligns the stp response buffer in DWORD alignment
127 #define scic_sds_stp_request_align_response_buffer(address) \
128 ((SATA_FIS_REG_D2H_T *)( \
129 (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \
130 & ~(sizeof(U32)- 1) \
134 * This macro returns the DWORD-aligned stp response buffer
136 #define scic_sds_stp_request_get_response_buffer(memory) \
137 ((SATA_FIS_REG_D2H_T *) \
138 ((char *)scic_sds_stp_request_align_response_buffer( \
139 (char *)scic_sds_stp_request_get_response_buffer_unaligned(memory) \
144 * This macro returns the address of the task context buffer in the io
147 #define scic_sds_stp_request_get_task_context_buffer_unaligned(memory) \
148 ((SCU_TASK_CONTEXT_T *)( \
149 ((char *)(scic_sds_stp_request_get_response_buffer(memory))) \
150 + sizeof(SCI_SSP_RESPONSE_IU_T) \
154 * This macro returns the aligned task context buffer
156 #define scic_sds_stp_request_get_task_context_buffer(memory) \
157 ((SCU_TASK_CONTEXT_T *)( \
158 ((char *)scic_sds_request_align_task_context_buffer( \
159 (char *)scic_sds_stp_request_get_task_context_buffer_unaligned(memory)) \
163 * This macro returns the address of the sgl elment pairs in the io request
166 #define scic_sds_stp_request_get_sgl_element_buffer(memory) \
167 ((SCU_SGL_ELEMENT_PAIR_T *)( \
168 ((char *)(scic_sds_stp_request_get_task_context_buffer(memory))) \
169 + sizeof(SCU_TASK_CONTEXT_T) \
174 * This method return the memory space commonly required for STP IO and
180 U32 scic_sds_stp_common_request_get_object_size(void)
182 return sizeof(SCIC_SDS_STP_REQUEST_T)
183 + sizeof(SATA_FIS_REG_H2D_T)
185 + sizeof(SATA_FIS_REG_D2H_T)
187 + sizeof(SCU_TASK_CONTEXT_T)
193 * This method return the memory space required for STP PIO requests.
197 U32 scic_sds_stp_request_get_object_size(void)
199 return scic_sds_stp_common_request_get_object_size()
200 + sizeof(SCU_SGL_ELEMENT_PAIR_T) * SCU_MAX_SGL_ELEMENT_PAIRS;
205 * This method return the memory space required for STP task requests.
209 U32 scic_sds_stp_task_request_get_object_size(void)
211 return scic_sds_stp_common_request_get_object_size();
218 * @param[in] this_request
220 void scic_sds_stp_request_assign_buffers(
221 SCIC_SDS_REQUEST_T * request
224 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
226 this_request->parent.command_buffer =
227 scic_sds_stp_request_get_h2d_reg_buffer(this_request);
228 this_request->parent.response_buffer =
229 scic_sds_stp_request_get_response_buffer(this_request);
230 this_request->parent.sgl_element_pair_buffer =
231 scic_sds_stp_request_get_sgl_element_buffer(this_request);
232 this_request->parent.sgl_element_pair_buffer =
233 scic_sds_request_align_sgl_element_buffer(this_request->parent.sgl_element_pair_buffer);
235 if (this_request->parent.was_tag_assigned_by_user == FALSE)
237 this_request->parent.task_context_buffer =
238 scic_sds_stp_request_get_task_context_buffer(this_request);
243 * @brief This method is will fill in the SCU Task Context for any type of
244 * SATA request. This is called from the various SATA constructors.
246 * @pre The general io request construction is complete.
247 * @pre The buffer assignment for the command buffer is complete.
249 * @param[in] this_request The general IO request object which is to be used
250 * in constructing the SCU task context.
251 * @param[in] task_context The buffer pointer for the SCU task context which
252 * is being constructed.
256 * @todo Revisit task context construction to determine what is common for
257 * SSP/SMP/STP task context structures.
259 void scu_sata_reqeust_construct_task_context(
260 SCIC_SDS_REQUEST_T * this_request,
261 SCU_TASK_CONTEXT_T * task_context
264 SCI_PHYSICAL_ADDRESS physical_address;
265 SCIC_SDS_CONTROLLER_T *owning_controller;
266 SCIC_SDS_REMOTE_DEVICE_T *target_device;
267 SCIC_SDS_PORT_T *target_port;
269 owning_controller = scic_sds_request_get_controller(this_request);
270 target_device = scic_sds_request_get_device(this_request);
271 target_port = scic_sds_request_get_port(this_request);
273 // Fill in the TC with the its required data
274 task_context->abort = 0;
275 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
276 task_context->initiator_request = 1;
277 task_context->connection_rate =
278 scic_remote_device_get_connection_rate(target_device);
279 task_context->protocol_engine_index =
280 scic_sds_controller_get_protocol_engine_group(owning_controller);
281 task_context->logical_port_index =
282 scic_sds_port_get_index(target_port);
283 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP;
284 task_context->valid = SCU_TASK_CONTEXT_VALID;
285 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
287 task_context->remote_node_index =
288 scic_sds_remote_device_get_index(this_request->target_device);
289 task_context->command_code = 0;
291 task_context->link_layer_control = 0;
292 task_context->do_not_dma_ssp_good_response = 1;
293 task_context->strict_ordering = 0;
294 task_context->control_frame = 0;
295 task_context->timeout_enable = 0;
296 task_context->block_guard_enable = 0;
298 task_context->address_modifier = 0;
299 task_context->task_phase = 0x01;
301 task_context->ssp_command_iu_length =
302 (sizeof(SATA_FIS_REG_H2D_T) - sizeof(U32)) / sizeof(U32);
304 // Set the first word of the H2D REG FIS
305 task_context->type.words[0] = *(U32 *)this_request->command_buffer;
307 if (this_request->was_tag_assigned_by_user)
309 // Build the task context now since we have already read the data
310 this_request->post_context = (
311 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
313 scic_sds_controller_get_protocol_engine_group(owning_controller)
314 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
317 scic_sds_port_get_index(target_port)
318 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
320 | scic_sds_io_tag_get_index(this_request->io_tag)
325 // Build the task context now since we have already read the data
326 this_request->post_context = (
327 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
329 scic_sds_controller_get_protocol_engine_group(owning_controller)
330 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
333 scic_sds_port_get_index(target_port)
334 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
336 // This is not assigned because we have to wait until we get a TCi
340 // Copy the physical address for the command buffer to the SCU Task Context
341 // We must offset the command buffer by 4 bytes because the first 4 bytes are
342 // transferred in the body of the TC
343 scic_cb_io_request_get_physical_address(
344 scic_sds_request_get_controller(this_request),
346 ((char *)this_request->command_buffer) + sizeof(U32),
350 task_context->command_iu_upper =
351 sci_cb_physical_address_upper(physical_address);
352 task_context->command_iu_lower =
353 sci_cb_physical_address_lower(physical_address);
355 // SATA Requests do not have a response buffer
356 task_context->response_iu_upper = 0;
357 task_context->response_iu_lower = 0;
361 * This method will perform any general sata request construction.
363 * @todo What part of SATA IO request construction is general?
365 * @param[in] this_request
369 void scic_sds_stp_non_ncq_request_construct(
370 SCIC_SDS_REQUEST_T * this_request
373 this_request->has_started_substate_machine = TRUE;
377 * This method will perform request construction common to all types of
378 * STP requests that are optimized by the silicon (i.e. UDMA, NCQ).
380 * @param[in,out] this_request This parameter specifies the request to be
381 * constructed as an optimized request.
382 * @param[in] optimized_task_type This parameter specifies whether the
383 * request is to be an UDMA request or a NCQ request.
384 * - A value of 0 indicates UDMA.
385 * - A value of 1 indicates NCQ.
387 * @return This method returns an indication as to whether the construction
391 void scic_sds_stp_optimized_request_construct(
392 SCIC_SDS_REQUEST_T * this_request,
393 U8 optimized_task_type,
395 SCI_IO_REQUEST_DATA_DIRECTION data_direction
398 SCU_TASK_CONTEXT_T * task_context = this_request->task_context_buffer;
400 // Build the STP task context structure
401 scu_sata_reqeust_construct_task_context(this_request, task_context);
403 // Copy over the number of bytes to be transferred
404 task_context->transfer_length_bytes = transfer_length;
406 if ( data_direction == SCI_IO_REQUEST_DATA_OUT )
408 // The difference between the DMA IN and DMA OUT request task type
409 // values are consistent with the difference between FPDMA READ
410 // and FPDMA WRITE values. Add the supplied task type parameter
411 // to this difference to set the task type properly for this
412 // DATA OUT (WRITE) case.
413 task_context->task_type = optimized_task_type + (SCU_TASK_TYPE_DMA_OUT
414 - SCU_TASK_TYPE_DMA_IN);
418 // For the DATA IN (READ) case, simply save the supplied
419 // optimized task type.
420 task_context->task_type = optimized_task_type;
425 * This method performs the operations common to all SATA/STP requests
426 * utilizing the raw frame method.
428 * @param[in] this_request This parameter specifies the STP request object
429 * for which to construct a RAW command frame task context.
430 * @param[in] task_context This parameter specifies the SCU specific
431 * task context buffer to construct.
435 void scu_stp_raw_request_construct_task_context(
436 SCIC_SDS_STP_REQUEST_T * this_request,
437 SCU_TASK_CONTEXT_T * task_context
440 scu_sata_reqeust_construct_task_context(&this_request->parent, task_context);
442 task_context->control_frame = 0;
443 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
444 task_context->task_type = SCU_TASK_TYPE_SATA_RAW_FRAME;
445 task_context->type.stp.fis_type = SATA_FIS_TYPE_REGH2D;
446 task_context->transfer_length_bytes = sizeof(SATA_FIS_REG_H2D_T) - sizeof(U32);
450 * This method will construct the STP Non-data request and its associated
451 * TC data. A non-data request essentially behaves like a 0 length read
452 * request in the SCU.
454 * @param[in] this_request This parameter specifies the core request
455 * object to construction into an STP/SATA non-data request.
457 * @return This method currently always returns SCI_SUCCESS
459 SCI_STATUS scic_sds_stp_non_data_request_construct(
460 SCIC_SDS_REQUEST_T * this_request
463 scic_sds_stp_non_ncq_request_construct(this_request);
465 // Build the STP task context structure
466 scu_stp_raw_request_construct_task_context(
467 (SCIC_SDS_STP_REQUEST_T*) this_request,
468 this_request->task_context_buffer
471 sci_base_state_machine_construct(
472 &this_request->started_substate_machine,
473 &this_request->parent.parent,
474 scic_sds_stp_request_started_non_data_substate_table,
475 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
482 SCI_STATUS scic_sds_stp_soft_reset_request_construct(
483 SCIC_SDS_REQUEST_T * this_request
486 scic_sds_stp_non_ncq_request_construct(this_request);
488 // Build the STP task context structure
489 scu_stp_raw_request_construct_task_context(
490 (SCIC_SDS_STP_REQUEST_T*) this_request,
491 this_request->task_context_buffer
494 sci_base_state_machine_construct(
495 &this_request->started_substate_machine,
496 &this_request->parent.parent,
497 scic_sds_stp_request_started_soft_reset_substate_table,
498 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
505 * @brief This method constructs the SATA request object.
507 * @param[in] this_request
508 * @param[in] sat_protocol
509 * @param[in] transfer_length
510 * @param[in] data_direction
511 * @param[in] copy_rx_frame
512 * @param[in] do_translate_sgl This parameter specifies whether SGL
513 * translation should be performed or if the user is handling
518 SCI_STATUS scic_sds_io_request_construct_sata(
519 SCIC_SDS_REQUEST_T * this_request,
522 SCI_IO_REQUEST_DATA_DIRECTION data_direction,
524 BOOL do_translate_sgl
527 SCI_STATUS status = SCI_SUCCESS;
529 this_request->protocol = SCIC_STP_PROTOCOL;
531 this_request->sat_protocol = sat_protocol;
533 switch (sat_protocol)
535 case SAT_PROTOCOL_FPDMA:
536 scic_sds_stp_optimized_request_construct(
538 SCU_TASK_TYPE_FPDMAQ_READ,
543 // Copy over the SGL elements
544 if (do_translate_sgl == TRUE)
545 scic_sds_request_build_sgl(this_request);
548 case SAT_PROTOCOL_UDMA_DATA_IN:
549 case SAT_PROTOCOL_UDMA_DATA_OUT:
550 scic_sds_stp_non_ncq_request_construct(this_request);
552 scic_sds_stp_optimized_request_construct(
553 this_request, SCU_TASK_TYPE_DMA_IN, transfer_length, data_direction
556 // Copy over the SGL elements
557 if (do_translate_sgl == TRUE)
558 scic_sds_request_build_sgl(this_request);
560 sci_base_state_machine_construct(
561 &this_request->started_substate_machine,
562 &this_request->parent.parent,
563 scic_sds_stp_request_started_udma_substate_table,
564 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
568 case SAT_PROTOCOL_PIO_DATA_IN:
569 case SAT_PROTOCOL_PIO_DATA_OUT:
570 status = scic_sds_stp_pio_request_construct(
571 this_request, sat_protocol, copy_rx_frame);
574 case SAT_PROTOCOL_ATA_HARD_RESET:
575 case SAT_PROTOCOL_SOFT_RESET:
576 status = scic_sds_stp_soft_reset_request_construct(this_request);
579 case SAT_PROTOCOL_NON_DATA:
580 status = scic_sds_stp_non_data_request_construct(this_request);
583 #if !defined(DISABLE_ATAPI)
584 case SAT_PROTOCOL_PACKET_NON_DATA:
585 case SAT_PROTOCOL_PACKET_DMA_DATA_IN:
586 case SAT_PROTOCOL_PACKET_DMA_DATA_OUT:
587 case SAT_PROTOCOL_PACKET_PIO_DATA_IN:
588 case SAT_PROTOCOL_PACKET_PIO_DATA_OUT:
589 status = scic_sds_stp_packet_request_construct(this_request);
590 if (do_translate_sgl == TRUE)
591 scic_sds_request_build_sgl(this_request);
595 case SAT_PROTOCOL_DMA_QUEUED:
596 case SAT_PROTOCOL_DMA:
597 case SAT_PROTOCOL_DEVICE_DIAGNOSTIC:
598 case SAT_PROTOCOL_DEVICE_RESET:
599 case SAT_PROTOCOL_RETURN_RESPONSE_INFO:
602 sci_base_object_get_logger(this_request),
603 SCIC_LOG_OBJECT_STP_IO_REQUEST,
604 "SCIC IO Request 0x%x received un-handled SAT Protocol %d.\n",
605 this_request, sat_protocol
608 status = SCI_FAILURE;
612 if (status == SCI_SUCCESS)
614 scic_sds_request_initialize_state_logging(this_request);
616 sci_base_state_machine_change_state(
617 &this_request->parent.state_machine,
618 SCI_BASE_REQUEST_STATE_CONSTRUCTED
625 //****************************************************************************
626 //* SCIC Interface Implementation
627 //****************************************************************************
629 void scic_stp_io_request_set_ncq_tag(
630 SCI_IO_REQUEST_HANDLE_T scic_io_request,
635 * @note This could be made to return an error to the user if the user
636 * attempts to set the NCQ tag in the wrong state.
638 SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request;
639 this_request->task_context_buffer->type.stp.ncq_tag = ncq_tag;
642 // ---------------------------------------------------------------------------
644 void * scic_stp_io_request_get_h2d_reg_address(
645 SCI_IO_REQUEST_HANDLE_T scic_io_request
648 SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request;
650 return this_request->command_buffer;
653 // ---------------------------------------------------------------------------
655 void * scic_stp_io_request_get_d2h_reg_address(
656 SCI_IO_REQUEST_HANDLE_T scic_io_request
659 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)scic_io_request;
661 return &this_request->d2h_reg_fis;
665 * Get the next SGL element from the request.
666 * - Check on which SGL element pair we are working
667 * - if working on SLG pair element A
668 * - advance to element B
670 * - check to see if there are more SGL element pairs
671 * for this IO request
672 * - if there are more SGL element pairs
673 * - advance to the next pair and return element A
675 * @param[in] this_request
677 * @return SCU_SGL_ELEMENT_T*
679 SCU_SGL_ELEMENT_T * scic_sds_stp_request_pio_get_next_sgl(
680 SCIC_SDS_STP_REQUEST_T * this_request
683 SCU_SGL_ELEMENT_T * current_sgl;
685 if (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A)
688 (this_request->type.pio.request_current.sgl_pair->B.address_lower == 0)
689 && (this_request->type.pio.request_current.sgl_pair->B.address_upper == 0)
696 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_B;
697 current_sgl = &(this_request->type.pio.request_current.sgl_pair->B);
703 (this_request->type.pio.request_current.sgl_pair->next_pair_lower == 0)
704 && (this_request->type.pio.request_current.sgl_pair->next_pair_upper == 0)
711 this_request->type.pio.request_current.sgl_pair =
712 scic_sds_request_get_sgl_element_pair(
713 &(this_request->parent),
714 ++this_request->type.pio.sgl_pair_index
717 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A;
719 current_sgl = &(this_request->type.pio.request_current.sgl_pair->A);
727 * This method will construct the SATA PIO request.
729 * @param[in] scic_io_request The core request object which is cast to a SATA
730 * PIO request object.
732 * @return This method returns an indication as to whether the construction
734 * @retval SCI_SUCCESS Currently this method always returns this value.
736 SCI_STATUS scic_sds_stp_pio_request_construct(
737 SCIC_SDS_REQUEST_T * scic_io_request,
742 SCIC_SDS_STP_REQUEST_T * this_request;
744 this_request = (SCIC_SDS_STP_REQUEST_T *)scic_io_request;
746 scic_sds_stp_non_ncq_request_construct(&this_request->parent);
748 scu_stp_raw_request_construct_task_context(
749 this_request, this_request->parent.task_context_buffer
752 this_request->type.pio.current_transfer_bytes = 0;
753 this_request->type.pio.ending_error = 0;
754 this_request->type.pio.ending_status = 0;
756 this_request->type.pio.request_current.sgl_offset = 0;
757 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A;
758 this_request->type.pio.sat_protocol = sat_protocol;
759 this_request->type.pio.sgl_pair_index = 0;
761 if ((copy_rx_frame) || (sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT))
763 scic_sds_request_build_sgl(&this_request->parent);
764 // Since the IO request copy of the TC contains the same data as
765 // the actual TC this pointer is vaild for either.
766 this_request->type.pio.request_current.sgl_pair =
767 &this_request->parent.task_context_buffer->sgl_pair_ab;
771 // The user does not want the data copied to the SGL buffer location
772 this_request->type.pio.request_current.sgl_pair = NULL;
775 sci_base_state_machine_construct(
776 &this_request->parent.started_substate_machine,
777 &this_request->parent.parent.parent,
778 scic_sds_stp_request_started_pio_substate_table,
779 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
785 //******************************************************************************
786 //* STP NON-DATA STATE MACHINE
787 //******************************************************************************
790 * This method processes a TC completion. The expected TC completion is
791 * for the transmission of the H2D register FIS containing the SATA/STP
794 * @param[in] this_request
795 * @param[in] completion_code
797 * @return This method always successfully processes the TC completion.
798 * @retval SCI_SUCCESS This value is always returned.
801 SCI_STATUS scic_sds_stp_request_non_data_await_h2d_tc_completion_handler(
802 SCIC_SDS_REQUEST_T * this_request,
807 sci_base_object_get_logger(this_request),
808 SCIC_LOG_OBJECT_STP_IO_REQUEST,
809 "scic_sds_stp_request_non_data_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n",
810 this_request, completion_code
813 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
815 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
816 scic_sds_request_set_status(
817 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
820 sci_base_state_machine_change_state(
821 &this_request->started_substate_machine,
822 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
827 // All other completion status cause the IO to be complete. If a NAK
828 // was received, then it is up to the user to retry the request.
829 scic_sds_request_set_status(
831 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
832 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
835 sci_base_state_machine_change_state(
836 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
845 * This method processes frames received from the target while waiting
846 * for a device to host register FIS. If a non-register FIS is received
847 * during this time, it is treated as a protocol violation from an
850 * @param[in] request This parameter specifies the request for which a
851 * frame has been received.
852 * @param[in] frame_index This parameter specifies the index of the frame
853 * that has been received.
855 * @return Indicate if the received frame was processed successfully.
858 SCI_STATUS scic_sds_stp_request_non_data_await_d2h_frame_handler(
859 SCIC_SDS_REQUEST_T * request,
864 SATA_FIS_HEADER_T * frame_header;
866 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
868 // Save off the controller, so that we do not touch the request after it
870 SCIC_SDS_CONTROLLER_T * owning_controller = this_request->parent.owning_controller;
873 sci_base_object_get_logger(this_request),
874 SCIC_LOG_OBJECT_STP_IO_REQUEST,
875 "scic_sds_stp_request_non_data_await_d2h_frame_handler(0x%x, 0x%x) enter\n",
876 this_request, frame_index
879 status = scic_sds_unsolicited_frame_control_get_header(
880 &(owning_controller->uf_control),
882 (void**) &frame_header
885 if (status == SCI_SUCCESS)
887 switch (frame_header->fis_type)
889 case SATA_FIS_TYPE_REGD2H:
890 scic_sds_unsolicited_frame_control_get_buffer(
891 &(owning_controller->uf_control),
893 (void**) &frame_buffer
896 scic_sds_controller_copy_sata_response(
897 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer
900 // The command has completed with error
901 scic_sds_request_set_status(
902 &this_request->parent,
903 SCU_TASK_DONE_CHECK_RESPONSE,
904 SCI_FAILURE_IO_RESPONSE_VALID
910 sci_base_object_get_logger(this_request),
911 SCIC_LOG_OBJECT_STP_IO_REQUEST,
912 "IO Request:0x%x Frame Id:%d protocol violation occurred\n",
913 this_request, frame_index
916 scic_sds_request_set_status(
917 &this_request->parent,
918 SCU_TASK_DONE_UNEXP_FIS,
919 SCI_FAILURE_PROTOCOL_VIOLATION
924 sci_base_state_machine_change_state(
925 &this_request->parent.parent.state_machine,
926 SCI_BASE_REQUEST_STATE_COMPLETED
929 // Frame has been decoded return it to the controller
930 scic_sds_controller_release_frame(
931 owning_controller, frame_index
937 sci_base_object_get_logger(this_request),
938 SCIC_LOG_OBJECT_STP_IO_REQUEST,
939 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
940 this_request, frame_index, status
947 // ---------------------------------------------------------------------------
949 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T
950 scic_sds_stp_request_started_non_data_substate_handler_table
951 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_MAX_SUBSTATES] =
953 // SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
956 scic_sds_request_default_start_handler,
957 scic_sds_request_started_state_abort_handler,
958 scic_sds_request_default_complete_handler,
959 scic_sds_request_default_destruct_handler
961 scic_sds_stp_request_non_data_await_h2d_tc_completion_handler,
962 scic_sds_request_default_event_handler,
963 scic_sds_request_default_frame_handler
965 // SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
968 scic_sds_request_default_start_handler,
969 scic_sds_request_started_state_abort_handler,
970 scic_sds_request_default_complete_handler,
971 scic_sds_request_default_destruct_handler
973 scic_sds_request_default_tc_completion_handler,
974 scic_sds_request_default_event_handler,
975 scic_sds_stp_request_non_data_await_d2h_frame_handler
980 void scic_sds_stp_request_started_non_data_await_h2d_completion_enter(
981 SCI_BASE_OBJECT_T *object
984 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
988 scic_sds_stp_request_started_non_data_substate_handler_table,
989 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
992 scic_sds_remote_device_set_working_request(
993 this_request->target_device, this_request
998 void scic_sds_stp_request_started_non_data_await_d2h_enter(
999 SCI_BASE_OBJECT_T *object
1002 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1006 scic_sds_stp_request_started_non_data_substate_handler_table,
1007 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
1011 // ---------------------------------------------------------------------------
1013 SCI_BASE_STATE_T scic_sds_stp_request_started_non_data_substate_table
1014 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_MAX_SUBSTATES] =
1017 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE,
1018 scic_sds_stp_request_started_non_data_await_h2d_completion_enter,
1022 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE,
1023 scic_sds_stp_request_started_non_data_await_d2h_enter,
1028 //******************************************************************************
1029 //* STP PIO STATE MACHINE
1030 //******************************************************************************
1032 #define SCU_MAX_FRAME_BUFFER_SIZE 0x400 // 1K is the maximum SCU frame data payload
1035 * This function will transmit DATA_FIS from (current sgl + offset) for input parameter length.
1036 * current sgl and offset is alreay stored in the IO request
1038 * @param[in] this_request
1041 * @return SCI_STATUS
1044 SCI_STATUS scic_sds_stp_request_pio_data_out_trasmit_data_frame (
1045 SCIC_SDS_REQUEST_T * this_request,
1049 SCI_STATUS status = SCI_SUCCESS;
1050 SCU_SGL_ELEMENT_T * current_sgl;
1051 SCIC_SDS_STP_REQUEST_T * this_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *)this_request;
1053 // Recycle the TC and reconstruct it for sending out DATA FIS containing
1054 // for the data from current_sgl+offset for the input length
1055 SCU_TASK_CONTEXT_T * task_context = scic_sds_controller_get_task_context_buffer(
1056 this_request->owning_controller,
1057 this_request->io_tag
1060 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A)
1062 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A);
1066 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B);
1070 task_context->command_iu_upper = current_sgl->address_upper;
1071 task_context->command_iu_lower = current_sgl->address_lower;
1072 task_context->transfer_length_bytes = length;
1073 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
1075 // send the new TC out.
1076 status = this_request->owning_controller->state_handlers->parent.continue_io_handler(
1077 &this_request->owning_controller->parent,
1078 &this_request->target_device->parent,
1079 &this_request->parent
1089 * @param[in] this_request
1091 * @return SCI_STATUS
1094 SCI_STATUS scic_sds_stp_request_pio_data_out_transmit_data(
1095 SCIC_SDS_REQUEST_T * this_sds_request
1099 SCU_SGL_ELEMENT_T * current_sgl;
1101 U32 remaining_bytes_in_current_sgl = 0;
1102 SCI_STATUS status = SCI_SUCCESS;
1104 SCIC_SDS_STP_REQUEST_T * this_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *)this_sds_request;
1106 sgl_offset = this_sds_stp_request->type.pio.request_current.sgl_offset;
1108 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A)
1110 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A);
1111 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->A.length - sgl_offset;
1115 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B);
1116 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->B.length - sgl_offset;
1120 if (this_sds_stp_request->type.pio.pio_transfer_bytes > 0)
1122 if (this_sds_stp_request->type.pio.pio_transfer_bytes >= remaining_bytes_in_current_sgl )
1124 //recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = remaining_bytes_in_current_sgl
1125 status = scic_sds_stp_request_pio_data_out_trasmit_data_frame (this_sds_request, remaining_bytes_in_current_sgl);
1126 if (status == SCI_SUCCESS)
1128 this_sds_stp_request->type.pio.pio_transfer_bytes -= remaining_bytes_in_current_sgl;
1132 else if (this_sds_stp_request->type.pio.pio_transfer_bytes < remaining_bytes_in_current_sgl )
1134 //recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = type.pio.pio_transfer_bytes
1135 scic_sds_stp_request_pio_data_out_trasmit_data_frame (this_sds_request, this_sds_stp_request->type.pio.pio_transfer_bytes);
1137 if (status == SCI_SUCCESS)
1139 //Sgl offset will be adjusted and saved for future
1140 sgl_offset += this_sds_stp_request->type.pio.pio_transfer_bytes;
1141 current_sgl->address_lower += this_sds_stp_request->type.pio.pio_transfer_bytes;
1142 this_sds_stp_request->type.pio.pio_transfer_bytes = 0;
1147 if (status == SCI_SUCCESS)
1149 this_sds_stp_request->type.pio.request_current.sgl_offset = sgl_offset;
1156 * Copy the data from the buffer for the length specified to the IO reqeust
1157 * SGL specified data region.
1159 * @param[in] this_request The request that is used for the SGL processing.
1160 * @param[in] data_buffer The buffer of data to be copied.
1161 * @param[in] length The length of the data transfer.
1163 * @return SCI_STATUS
1166 SCI_STATUS scic_sds_stp_request_pio_data_in_copy_data_buffer(
1167 SCIC_SDS_STP_REQUEST_T * this_request,
1173 SCU_SGL_ELEMENT_T * current_sgl;
1176 U8 * source_address;
1178 // Initial setup to get the current working SGL and the offset within the buffer
1180 (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) ?
1181 &(this_request->type.pio.request_current.sgl_pair->A) :
1182 &(this_request->type.pio.request_current.sgl_pair->B) ;
1184 sgl_offset = this_request->type.pio.request_current.sgl_offset;
1186 source_address = data_buffer;
1187 data_offset = this_request->type.pio.current_transfer_bytes;
1188 status = SCI_SUCCESS;
1190 // While we are still doing Ok and there is more data to transfer
1193 && (status == SCI_SUCCESS)
1196 if (current_sgl->length == sgl_offset)
1198 // This SGL has been exauhasted so we need to get the next SGL
1199 current_sgl = scic_sds_stp_request_pio_get_next_sgl(this_request);
1201 if (current_sgl == NULL)
1202 status = SCI_FAILURE;
1208 #ifdef ENABLE_OSSL_COPY_BUFFER
1209 scic_cb_io_request_copy_buffer(this_request, data_buffer, data_offset, length);
1212 U8 * destination_address;
1215 destination_address = (U8 *)scic_cb_io_request_get_virtual_address_from_sgl(
1220 copy_length = MIN(length, current_sgl->length - sgl_offset);
1222 memcpy(destination_address, source_address, copy_length);
1224 length -= copy_length;
1225 sgl_offset += copy_length;
1226 data_offset += copy_length;
1227 source_address += copy_length;
1232 this_request->type.pio.request_current.sgl_offset = sgl_offset;
1238 * Copy the data buffer to the io request data region.
1240 * @param[in] this_request The PIO DATA IN request that is to receive the
1242 * @param[in] data_buffer The buffer to copy from.
1244 * @return SCI_STATUS
1247 SCI_STATUS scic_sds_stp_request_pio_data_in_copy_data(
1248 SCIC_SDS_STP_REQUEST_T * this_request,
1254 // If there is less than 1K remaining in the transfer request
1255 // copy just the data for the transfer
1256 if (this_request->type.pio.pio_transfer_bytes < SCU_MAX_FRAME_BUFFER_SIZE)
1258 status = scic_sds_stp_request_pio_data_in_copy_data_buffer(
1259 this_request,data_buffer,this_request->type.pio.pio_transfer_bytes);
1261 if (status == SCI_SUCCESS)
1263 // All data for this PIO request has now been copied, so we don't
1264 // technically need to update current_transfer_bytes here - just
1265 // doing it for completeness.
1266 this_request->type.pio.current_transfer_bytes += this_request->type.pio.pio_transfer_bytes;
1267 this_request->type.pio.pio_transfer_bytes = 0;
1272 // We are transferring the whole frame so copy
1273 status = scic_sds_stp_request_pio_data_in_copy_data_buffer(
1274 this_request, data_buffer, SCU_MAX_FRAME_BUFFER_SIZE);
1276 if (status == SCI_SUCCESS)
1278 this_request->type.pio.pio_transfer_bytes -= SCU_MAX_FRAME_BUFFER_SIZE;
1279 this_request->type.pio.current_transfer_bytes += SCU_MAX_FRAME_BUFFER_SIZE;
1289 * @param[in] this_request
1290 * @param[in] completion_code
1292 * @return SCI_STATUS
1295 SCI_STATUS scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler(
1296 SCIC_SDS_REQUEST_T * this_request,
1300 SCI_STATUS status = SCI_SUCCESS;
1303 sci_base_object_get_logger(this_request),
1304 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1305 "scic_sds_stp_request_pio_data_in_await_h2d_completion_tc_completion_handler(0x%x, 0x%x) enter\n",
1306 this_request, completion_code
1309 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
1311 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1312 scic_sds_request_set_status(
1313 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1316 sci_base_state_machine_change_state(
1317 &this_request->started_substate_machine,
1318 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1323 // All other completion status cause the IO to be complete. If a NAK
1324 // was received, then it is up to the user to retry the request.
1325 scic_sds_request_set_status(
1327 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1328 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1331 sci_base_state_machine_change_state(
1332 &this_request->parent.state_machine,
1333 SCI_BASE_REQUEST_STATE_COMPLETED
1344 * @param[in] this_request
1345 * @param[in] frame_index
1347 * @return SCI_STATUS
1350 SCI_STATUS scic_sds_stp_request_pio_await_frame_frame_handler(
1351 SCIC_SDS_REQUEST_T * request,
1356 SATA_FIS_HEADER_T * frame_header;
1358 SCIC_SDS_STP_REQUEST_T * this_request;
1359 SCIC_SDS_CONTROLLER_T * owning_controller;
1361 this_request = (SCIC_SDS_STP_REQUEST_T *)request;
1363 // Save off the controller, so that we do not touch the request after it
1365 owning_controller = this_request->parent.owning_controller;
1368 sci_base_object_get_logger(this_request),
1369 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1370 "scic_sds_stp_request_pio_data_in_await_frame_frame_handler(0x%x, 0x%x) enter\n",
1371 this_request, frame_index
1374 status = scic_sds_unsolicited_frame_control_get_header(
1375 &(owning_controller->uf_control),
1377 (void**) &frame_header
1380 if (status == SCI_SUCCESS)
1382 switch (frame_header->fis_type)
1384 case SATA_FIS_TYPE_PIO_SETUP:
1385 // Get from the frame buffer the PIO Setup Data
1386 scic_sds_unsolicited_frame_control_get_buffer(
1387 &(owning_controller->uf_control),
1389 (void**) &frame_buffer
1392 // Get the data from the PIO Setup
1393 // The SCU Hardware returns first word in the frame_header and the rest
1394 // of the data is in the frame buffer so we need to back up one dword
1395 this_request->type.pio.pio_transfer_bytes =
1396 (U16)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->transfter_count;
1397 this_request->type.pio.ending_status =
1398 (U8)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->ending_status;
1400 scic_sds_controller_copy_sata_response(
1401 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer
1404 this_request->d2h_reg_fis.status =
1405 this_request->type.pio.ending_status;
1407 //The next state is dependent on whether the request was PIO Data-in or Data out
1408 if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_IN)
1410 sci_base_state_machine_change_state(
1411 &this_request->parent.started_substate_machine,
1412 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1415 else if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT)
1418 status = scic_sds_stp_request_pio_data_out_transmit_data ( request);
1419 if (status == SCI_SUCCESS)
1421 sci_base_state_machine_change_state(
1422 &this_request->parent.started_substate_machine,
1423 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1429 case SATA_FIS_TYPE_SETDEVBITS:
1430 sci_base_state_machine_change_state(
1431 &this_request->parent.started_substate_machine,
1432 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1436 case SATA_FIS_TYPE_REGD2H:
1437 if ( (frame_header->status & ATA_STATUS_REG_BSY_BIT) == 0)
1439 scic_sds_unsolicited_frame_control_get_buffer(
1440 &(owning_controller->uf_control),
1442 (void**) &frame_buffer
1445 scic_sds_controller_copy_sata_response(
1446 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer);
1448 scic_sds_request_set_status(
1449 &this_request->parent,
1450 SCU_TASK_DONE_CHECK_RESPONSE,
1451 SCI_FAILURE_IO_RESPONSE_VALID
1454 sci_base_state_machine_change_state(
1455 &this_request->parent.parent.state_machine,
1456 SCI_BASE_REQUEST_STATE_COMPLETED
1461 // Now why is the drive sending a D2H Register FIS when it is still busy?
1462 // Do nothing since we are still in the right state.
1464 sci_base_object_get_logger(this_request),
1465 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1466 "SCIC PIO Request 0x%x received D2H Register FIS with BSY status 0x%x\n",
1467 this_request, frame_header->status
1476 // Frame is decoded return it to the controller
1477 scic_sds_controller_release_frame(
1485 sci_base_object_get_logger(this_request),
1486 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1487 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
1488 this_request, frame_index, status
1498 * @param[in] this_request
1499 * @param[in] frame_index
1501 * @return SCI_STATUS
1504 SCI_STATUS scic_sds_stp_request_pio_data_in_await_data_frame_handler(
1505 SCIC_SDS_REQUEST_T * request,
1510 SATA_FIS_HEADER_T * frame_header;
1511 SATA_FIS_DATA_T * frame_buffer;
1512 SCIC_SDS_STP_REQUEST_T * this_request;
1513 SCIC_SDS_CONTROLLER_T * owning_controller;
1515 this_request = (SCIC_SDS_STP_REQUEST_T *)request;
1517 // Save off the controller, so that we do not touch the request after it
1519 owning_controller = this_request->parent.owning_controller;
1522 sci_base_object_get_logger(this_request),
1523 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1524 "scic_sds_stp_request_pio_data_in_await_data_frame_handler(0x%x, 0x%x) enter\n",
1525 this_request, frame_index
1528 status = scic_sds_unsolicited_frame_control_get_header(
1529 &(owning_controller->uf_control),
1531 (void**) &frame_header
1534 if (status == SCI_SUCCESS)
1536 if (frame_header->fis_type == SATA_FIS_TYPE_DATA)
1538 if (this_request->type.pio.request_current.sgl_pair == NULL)
1540 this_request->parent.saved_rx_frame_index = frame_index;
1541 this_request->type.pio.pio_transfer_bytes = 0;
1545 status = scic_sds_unsolicited_frame_control_get_buffer(
1546 &(owning_controller->uf_control),
1548 (void**) &frame_buffer
1551 status = scic_sds_stp_request_pio_data_in_copy_data(this_request, (U8 *)frame_buffer);
1553 // Frame is decoded return it to the controller
1554 scic_sds_controller_release_frame(
1560 // Check for the end of the transfer, are there more bytes remaining
1561 // for this data transfer
1563 (status == SCI_SUCCESS)
1564 && (this_request->type.pio.pio_transfer_bytes == 0)
1567 if ((this_request->type.pio.ending_status & ATA_STATUS_REG_BSY_BIT) == 0)
1569 scic_sds_request_set_status(
1570 &this_request->parent,
1571 SCU_TASK_DONE_CHECK_RESPONSE,
1572 SCI_FAILURE_IO_RESPONSE_VALID
1575 sci_base_state_machine_change_state(
1576 &this_request->parent.parent.state_machine,
1577 SCI_BASE_REQUEST_STATE_COMPLETED
1582 sci_base_state_machine_change_state(
1583 &this_request->parent.started_substate_machine,
1584 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1592 sci_base_object_get_logger(this_request),
1593 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1594 "SCIC PIO Request 0x%x received frame %d with fis type 0x%02x when expecting a data fis.\n",
1595 this_request, frame_index, frame_header->fis_type
1598 scic_sds_request_set_status(
1599 &this_request->parent,
1601 SCI_FAILURE_IO_REQUIRES_SCSI_ABORT
1604 sci_base_state_machine_change_state(
1605 &this_request->parent.parent.state_machine,
1606 SCI_BASE_REQUEST_STATE_COMPLETED
1609 // Frame is decoded return it to the controller
1610 scic_sds_controller_release_frame(
1619 sci_base_object_get_logger(this_request),
1620 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1621 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
1622 this_request, frame_index, status
1633 * @param[in] this_request
1634 * @param[in] completion_code
1636 * @return SCI_STATUS
1639 SCI_STATUS scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler(
1641 SCIC_SDS_REQUEST_T * this_request,
1645 SCI_STATUS status = SCI_SUCCESS;
1646 BOOL all_frames_transferred = FALSE;
1648 SCIC_SDS_STP_REQUEST_T *this_scic_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *) this_request;
1651 sci_base_object_get_logger(this_request),
1652 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1653 "scic_sds_stp_request_pio_data_in_await_h2d_completion_tc_completion_handler(0x%x, 0x%x) enter\n",
1654 this_request, completion_code
1657 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
1659 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1661 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes != 0)
1663 status = scic_sds_stp_request_pio_data_out_transmit_data ( this_request);
1664 if (status == SCI_SUCCESS)
1666 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0)
1667 all_frames_transferred = TRUE;
1670 else if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0)
1672 //this will happen if the all data is written at the first time after the pio setup fis is received
1673 all_frames_transferred = TRUE;
1676 //all data transferred.
1677 if (all_frames_transferred)
1679 //Change the state to SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_FRAME_SUBSTATE
1680 //and wait for PIO_SETUP fis / or D2H REg fis.
1681 sci_base_state_machine_change_state(
1682 &this_request->started_substate_machine,
1683 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1689 // All other completion status cause the IO to be complete. If a NAK
1690 // was received, then it is up to the user to retry the request.
1691 scic_sds_request_set_status(
1693 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1694 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1697 sci_base_state_machine_change_state(
1698 &this_request->parent.state_machine,
1699 SCI_BASE_REQUEST_STATE_COMPLETED
1708 * This method will handle any link layer events while waiting for the data
1711 * @param[in] request This is the request which is receiving the event.
1712 * @param[in] event_code This is the event code that the request on which the
1713 * request is expected to take action.
1715 * @return SCI_STATUS
1716 * @retval SCI_SUCCESS
1717 * @retval SCI_FAILURE
1720 SCI_STATUS scic_sds_stp_request_pio_data_in_await_data_event_handler(
1721 SCIC_SDS_REQUEST_T * request,
1727 switch (scu_get_event_specifier(event_code))
1729 case SCU_TASK_DONE_CRC_ERR << SCU_EVENT_SPECIFIC_CODE_SHIFT:
1730 // We are waiting for data and the SCU has R_ERR the data frame.
1731 // Go back to waiting for the D2H Register FIS
1732 sci_base_state_machine_change_state(
1733 &request->started_substate_machine,
1734 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1737 status = SCI_SUCCESS;
1742 sci_base_object_get_logger(request),
1743 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1744 "SCIC PIO Request 0x%x received unexpected event 0x%08x\n",
1748 /// @todo Should we fail the PIO request when we get an unexpected event?
1749 status = SCI_FAILURE;
1756 // ---------------------------------------------------------------------------
1758 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T
1759 scic_sds_stp_request_started_pio_substate_handler_table
1760 [SCIC_SDS_STP_REQUEST_STARTED_PIO_MAX_SUBSTATES] =
1762 // SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
1765 scic_sds_request_default_start_handler,
1766 scic_sds_request_started_state_abort_handler,
1767 scic_sds_request_default_complete_handler,
1768 scic_sds_request_default_destruct_handler
1770 scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler,
1771 scic_sds_request_default_event_handler,
1772 scic_sds_request_default_frame_handler
1774 // SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1777 scic_sds_request_default_start_handler,
1778 //scic_sds_stp_pio_request_data_in_await_frame_abort_handler,
1779 scic_sds_request_started_state_abort_handler,
1780 scic_sds_request_default_complete_handler,
1781 scic_sds_request_default_destruct_handler
1783 scic_sds_request_default_tc_completion_handler,
1784 scic_sds_request_default_event_handler,
1785 scic_sds_stp_request_pio_await_frame_frame_handler
1787 // SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1790 scic_sds_request_default_start_handler,
1791 //scic_sds_stp_pio_request_data_in_await_data_abort_handler,
1792 scic_sds_request_started_state_abort_handler,
1793 scic_sds_request_default_complete_handler,
1794 scic_sds_request_default_destruct_handler
1796 scic_sds_request_default_tc_completion_handler,
1797 scic_sds_stp_request_pio_data_in_await_data_event_handler,
1798 scic_sds_stp_request_pio_data_in_await_data_frame_handler
1800 //SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1803 scic_sds_request_default_start_handler,
1804 scic_sds_request_started_state_abort_handler,
1805 scic_sds_request_default_complete_handler,
1806 scic_sds_request_default_destruct_handler
1808 scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler,
1809 scic_sds_request_default_event_handler,
1810 scic_sds_request_default_frame_handler
1815 void scic_sds_stp_request_started_pio_await_h2d_completion_enter(
1816 SCI_BASE_OBJECT_T *object
1819 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1823 scic_sds_stp_request_started_pio_substate_handler_table,
1824 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
1827 scic_sds_remote_device_set_working_request(
1828 this_request->target_device, this_request);
1832 void scic_sds_stp_request_started_pio_await_frame_enter(
1833 SCI_BASE_OBJECT_T *object
1836 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1840 scic_sds_stp_request_started_pio_substate_handler_table,
1841 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1846 void scic_sds_stp_request_started_pio_data_in_await_data_enter(
1847 SCI_BASE_OBJECT_T *object
1850 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1854 scic_sds_stp_request_started_pio_substate_handler_table,
1855 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1860 void scic_sds_stp_request_started_pio_data_out_transmit_data_enter(
1861 SCI_BASE_OBJECT_T *object
1864 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1868 scic_sds_stp_request_started_pio_substate_handler_table,
1869 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1873 // ---------------------------------------------------------------------------
1876 scic_sds_stp_request_started_pio_substate_table
1877 [SCIC_SDS_STP_REQUEST_STARTED_PIO_MAX_SUBSTATES] =
1880 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE,
1881 scic_sds_stp_request_started_pio_await_h2d_completion_enter,
1885 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE,
1886 scic_sds_stp_request_started_pio_await_frame_enter,
1890 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE,
1891 scic_sds_stp_request_started_pio_data_in_await_data_enter,
1895 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE,
1896 scic_sds_stp_request_started_pio_data_out_transmit_data_enter,
1901 //******************************************************************************
1902 //* UDMA REQUEST STATE MACHINE
1903 //******************************************************************************
1906 void scic_sds_stp_request_udma_complete_request(
1907 SCIC_SDS_REQUEST_T * this_request,
1909 SCI_STATUS sci_status
1912 scic_sds_request_set_status(
1913 this_request, scu_status, sci_status
1916 sci_base_state_machine_change_state(
1917 &this_request->parent.state_machine,
1918 SCI_BASE_REQUEST_STATE_COMPLETED
1925 * @param[in] this_request
1926 * @param[in] frame_index
1928 * @return SCI_STATUS
1931 SCI_STATUS scic_sds_stp_request_udma_general_frame_handler(
1932 SCIC_SDS_REQUEST_T * this_request,
1937 SATA_FIS_HEADER_T * frame_header;
1941 sci_base_object_get_logger(this_request),
1942 SCIC_LOG_OBJECT_STP_IO_REQUEST,
1943 "scic_sds_stp_pio_request_data_in_await_frame_frame_handler(0x%x, 0x%x) enter\n",
1944 this_request, frame_index
1947 status = scic_sds_unsolicited_frame_control_get_header(
1948 &this_request->owning_controller->uf_control,
1950 (void**) &frame_header
1954 (status == SCI_SUCCESS)
1955 && (frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
1958 scic_sds_unsolicited_frame_control_get_buffer(
1959 &this_request->owning_controller->uf_control,
1961 (void**) &frame_buffer
1964 scic_sds_controller_copy_sata_response(
1965 &((SCIC_SDS_STP_REQUEST_T *)this_request)->d2h_reg_fis,
1966 (U32 *)frame_header,
1971 scic_sds_controller_release_frame(
1972 this_request->owning_controller, frame_index);
1978 * @brief This method process TC completions while in the state where
1979 * we are waiting for TC completions.
1981 * @param[in] this_request
1982 * @param[in] completion_code
1984 * @return SCI_STATUS
1987 SCI_STATUS scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler(
1988 SCIC_SDS_REQUEST_T * request,
1992 SCI_STATUS status = SCI_SUCCESS;
1993 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
1995 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
1997 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1998 scic_sds_stp_request_udma_complete_request(
1999 &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS
2003 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS):
2004 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
2005 // We must check ther response buffer to see if the D2H Register FIS was
2006 // received before we got the TC completion.
2007 if (this_request->d2h_reg_fis.fis_type == SATA_FIS_TYPE_REGD2H)
2009 scic_sds_remote_device_suspend(
2010 this_request->parent.target_device,
2011 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))
2014 scic_sds_stp_request_udma_complete_request(
2015 &this_request->parent,
2016 SCU_TASK_DONE_CHECK_RESPONSE,
2017 SCI_FAILURE_IO_RESPONSE_VALID
2022 // If we have an error completion status for the TC then we can expect a
2023 // D2H register FIS from the device so we must change state to wait for it
2024 sci_base_state_machine_change_state(
2025 &this_request->parent.started_substate_machine,
2026 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
2031 /// @todo Check to see if any of these completion status need to wait for
2032 /// the device to host register fis.
2033 /// @todo We can retry the command for SCU_TASK_DONE_CMD_LL_R_ERR - this comes only for B0
2034 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_INV_FIS_LEN):
2035 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
2036 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR):
2037 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR):
2038 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CRC_ERR):
2039 scic_sds_remote_device_suspend(
2040 this_request->parent.target_device,
2041 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))
2043 // Fall through to the default case
2045 // All other completion status cause the IO to be complete.
2047 sci_base_object_get_logger(&this_request->parent),
2048 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2049 "SCIC IO Request 0x%x returning CONTROLLER_SPECIFIC_IO_ERR for completion code 0x%x\n",
2050 &this_request->parent, completion_code
2052 scic_sds_stp_request_udma_complete_request(
2053 &this_request->parent,
2054 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
2055 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2064 SCI_STATUS scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler(
2065 SCIC_SDS_REQUEST_T * this_request,
2071 // Use the general frame handler to copy the resposne data
2072 status = scic_sds_stp_request_udma_general_frame_handler(this_request, frame_index);
2074 if (status == SCI_SUCCESS)
2076 scic_sds_stp_request_udma_complete_request(
2078 SCU_TASK_DONE_CHECK_RESPONSE,
2079 SCI_FAILURE_IO_RESPONSE_VALID
2086 // ---------------------------------------------------------------------------
2088 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T
2089 scic_sds_stp_request_started_udma_substate_handler_table
2090 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_MAX_SUBSTATES] =
2092 // SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
2095 scic_sds_request_default_start_handler,
2096 scic_sds_request_started_state_abort_handler,
2097 scic_sds_request_default_complete_handler,
2098 scic_sds_request_default_destruct_handler
2100 scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler,
2101 scic_sds_request_default_event_handler,
2102 scic_sds_stp_request_udma_general_frame_handler
2104 // SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
2107 scic_sds_request_default_start_handler,
2108 scic_sds_request_started_state_abort_handler,
2109 scic_sds_request_default_complete_handler,
2110 scic_sds_request_default_destruct_handler
2112 scic_sds_request_default_tc_completion_handler,
2113 scic_sds_request_default_event_handler,
2114 scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler
2124 void scic_sds_stp_request_started_udma_await_tc_completion_enter(
2125 SCI_BASE_OBJECT_T *object
2128 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2132 scic_sds_stp_request_started_udma_substate_handler_table,
2133 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
2138 * This state is entered when there is an TC completion failure. The hardware
2139 * received an unexpected condition while processing the IO request and now
2140 * will UF the D2H register FIS to complete the IO.
2145 void scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter(
2146 SCI_BASE_OBJECT_T *object
2149 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2153 scic_sds_stp_request_started_udma_substate_handler_table,
2154 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
2158 // ---------------------------------------------------------------------------
2161 scic_sds_stp_request_started_udma_substate_table
2162 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_MAX_SUBSTATES] =
2165 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE,
2166 scic_sds_stp_request_started_udma_await_tc_completion_enter,
2170 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE,
2171 scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter,
2176 //******************************************************************************
2177 //* STP SOFT RESET STATE MACHINE
2178 //******************************************************************************
2181 * This method processes a TC completion. The expected TC completion is
2182 * for the transmission of the H2D register FIS containing the SATA/STP
2185 * @param[in] this_request
2186 * @param[in] completion_code
2188 * @return This method always successfully processes the TC completion.
2189 * @retval SCI_SUCCESS This value is always returned.
2192 SCI_STATUS scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler(
2193 SCIC_SDS_REQUEST_T * this_request,
2198 sci_base_object_get_logger(this_request),
2199 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2200 "scic_sds_stp_request_soft_reset_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n",
2201 this_request, completion_code
2204 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
2206 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
2207 scic_sds_request_set_status(
2208 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
2211 sci_base_state_machine_change_state(
2212 &this_request->started_substate_machine,
2213 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
2218 // All other completion status cause the IO to be complete. If a NAK
2219 // was received, then it is up to the user to retry the request.
2220 scic_sds_request_set_status(
2222 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
2223 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2226 sci_base_state_machine_change_state(
2227 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
2236 * This method processes a TC completion. The expected TC completion is
2237 * for the transmission of the H2D register FIS containing the SATA/STP
2240 * @param[in] this_request
2241 * @param[in] completion_code
2243 * @return This method always successfully processes the TC completion.
2244 * @retval SCI_SUCCESS This value is always returned.
2247 SCI_STATUS scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler(
2248 SCIC_SDS_REQUEST_T * this_request,
2253 sci_base_object_get_logger(this_request),
2254 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2255 "scic_sds_stp_request_soft_reset_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n",
2256 this_request, completion_code
2259 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
2261 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
2262 scic_sds_request_set_status(
2263 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
2266 sci_base_state_machine_change_state(
2267 &this_request->started_substate_machine,
2268 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
2273 // All other completion status cause the IO to be complete. If a NAK
2274 // was received, then it is up to the user to retry the request.
2275 scic_sds_request_set_status(
2277 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
2278 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2281 sci_base_state_machine_change_state(
2282 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
2291 * This method processes frames received from the target while waiting
2292 * for a device to host register FIS. If a non-register FIS is received
2293 * during this time, it is treated as a protocol violation from an
2296 * @param[in] request This parameter specifies the request for which a
2297 * frame has been received.
2298 * @param[in] frame_index This parameter specifies the index of the frame
2299 * that has been received.
2301 * @return Indicate if the received frame was processed successfully.
2304 SCI_STATUS scic_sds_stp_request_soft_reset_await_d2h_frame_handler(
2305 SCIC_SDS_REQUEST_T * request,
2310 SATA_FIS_HEADER_T * frame_header;
2312 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
2314 // Save off the controller, so that we do not touch the request after it
2316 SCIC_SDS_CONTROLLER_T * owning_controller = this_request->parent.owning_controller;
2319 sci_base_object_get_logger(this_request),
2320 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2321 "scic_sds_stp_request_soft_reset_await_d2h_frame_handler(0x%x, 0x%x) enter\n",
2322 this_request, frame_index
2325 status = scic_sds_unsolicited_frame_control_get_header(
2326 &(owning_controller->uf_control),
2328 (void**) &frame_header
2331 if (status == SCI_SUCCESS)
2333 switch (frame_header->fis_type)
2335 case SATA_FIS_TYPE_REGD2H:
2336 scic_sds_unsolicited_frame_control_get_buffer(
2337 &(owning_controller->uf_control),
2339 (void**) &frame_buffer
2342 scic_sds_controller_copy_sata_response(
2343 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer
2346 // The command has completed with error
2347 scic_sds_request_set_status(
2348 &this_request->parent,
2349 SCU_TASK_DONE_CHECK_RESPONSE,
2350 SCI_FAILURE_IO_RESPONSE_VALID
2356 sci_base_object_get_logger(this_request),
2357 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2358 "IO Request:0x%x Frame Id:%d protocol violation occurred\n",
2359 this_request, frame_index
2362 scic_sds_request_set_status(
2363 &this_request->parent,
2364 SCU_TASK_DONE_UNEXP_FIS,
2365 SCI_FAILURE_PROTOCOL_VIOLATION
2370 sci_base_state_machine_change_state(
2371 &this_request->parent.parent.state_machine,
2372 SCI_BASE_REQUEST_STATE_COMPLETED
2375 // Frame has been decoded return it to the controller
2376 scic_sds_controller_release_frame(
2377 owning_controller, frame_index
2383 sci_base_object_get_logger(this_request),
2384 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2385 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
2386 this_request, frame_index, status
2393 // ---------------------------------------------------------------------------
2395 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T
2396 scic_sds_stp_request_started_soft_reset_substate_handler_table
2397 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_MAX_SUBSTATES] =
2399 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
2402 scic_sds_request_default_start_handler,
2403 scic_sds_request_started_state_abort_handler,
2404 scic_sds_request_default_complete_handler,
2405 scic_sds_request_default_destruct_handler
2407 scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler,
2408 scic_sds_request_default_event_handler,
2409 scic_sds_request_default_frame_handler
2411 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
2414 scic_sds_request_default_start_handler,
2415 scic_sds_request_started_state_abort_handler,
2416 scic_sds_request_default_complete_handler,
2417 scic_sds_request_default_destruct_handler
2419 scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler,
2420 scic_sds_request_default_event_handler,
2421 scic_sds_request_default_frame_handler
2423 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
2426 scic_sds_request_default_start_handler,
2427 scic_sds_request_started_state_abort_handler,
2428 scic_sds_request_default_complete_handler,
2429 scic_sds_request_default_destruct_handler
2431 scic_sds_request_default_tc_completion_handler,
2432 scic_sds_request_default_event_handler,
2433 scic_sds_stp_request_soft_reset_await_d2h_frame_handler
2438 void scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter(
2439 SCI_BASE_OBJECT_T *object
2442 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2446 scic_sds_stp_request_started_soft_reset_substate_handler_table,
2447 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
2450 scic_sds_remote_device_set_working_request(
2451 this_request->target_device, this_request
2456 void scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter(
2457 SCI_BASE_OBJECT_T *object
2461 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2462 SATA_FIS_REG_H2D_T *h2d_fis;
2463 SCU_TASK_CONTEXT_T *task_context;
2465 // Clear the SRST bit
2466 h2d_fis = scic_stp_io_request_get_h2d_reg_address(this_request);
2467 h2d_fis->control = 0;
2469 // Clear the TC control bit
2470 task_context = scic_sds_controller_get_task_context_buffer(
2471 this_request->owning_controller, this_request->io_tag);
2472 task_context->control_frame = 0;
2474 status = this_request->owning_controller->state_handlers->parent.continue_io_handler(
2475 &this_request->owning_controller->parent,
2476 &this_request->target_device->parent,
2477 &this_request->parent
2480 if (status == SCI_SUCCESS)
2484 scic_sds_stp_request_started_soft_reset_substate_handler_table,
2485 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
2491 void scic_sds_stp_request_started_soft_reset_await_d2h_response_enter(
2492 SCI_BASE_OBJECT_T *object
2495 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2499 scic_sds_stp_request_started_soft_reset_substate_handler_table,
2500 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
2504 // ---------------------------------------------------------------------------
2507 scic_sds_stp_request_started_soft_reset_substate_table
2508 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_MAX_SUBSTATES] =
2511 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE,
2512 scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter,
2516 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE,
2517 scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter,
2521 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE,
2522 scic_sds_stp_request_started_soft_reset_await_d2h_response_enter,
2527 // ---------------------------------------------------------------------------
2529 SCI_STATUS scic_io_request_construct_basic_sata(
2530 SCI_IO_REQUEST_HANDLE_T scic_io_request
2534 SCIC_SDS_REQUEST_T * request = (SCIC_SDS_REQUEST_T *)scic_io_request;
2537 sci_base_object_get_logger(scic_io_request),
2538 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2539 "scic_io_request_construct_basic_sata(0x%x) enter\n",
2543 status = scic_sds_io_request_construct_sata(
2545 scic_cb_request_get_sat_protocol(request->user_request),
2546 scic_cb_io_request_get_transfer_length(request->user_request),
2547 scic_cb_io_request_get_data_direction(request->user_request),
2548 scic_cb_io_request_do_copy_rx_frames(request->user_request),
2555 // ---------------------------------------------------------------------------
2557 SCI_STATUS scic_io_request_construct_advanced_sata(
2558 SCI_IO_REQUEST_HANDLE_T scic_io_request,
2559 SCIC_IO_SATA_PARAMETERS_T * io_parameters
2563 SCIC_SDS_REQUEST_T * request = (SCIC_SDS_REQUEST_T *)scic_io_request;
2566 sci_base_object_get_logger(scic_io_request),
2567 SCIC_LOG_OBJECT_STP_IO_REQUEST,
2568 "scic_io_request_construct_basic_sata(0x%x) enter\n",
2572 status = scic_sds_io_request_construct_sata(
2574 scic_cb_request_get_sat_protocol(request->user_request),
2575 scic_sds_request_get_sgl_element_pair(request, 0)->A.length,
2576 scic_cb_io_request_get_data_direction(request->user_request),
2577 scic_cb_io_request_do_copy_rx_frames(request->user_request),
2578 io_parameters->do_translate_sgl