1230557Sjimharris/*-
2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license.  When using or
3230557Sjimharris * redistributing this file, you may do so under either license.
4230557Sjimharris *
5230557Sjimharris * GPL LICENSE SUMMARY
6230557Sjimharris *
7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8230557Sjimharris *
9230557Sjimharris * This program is free software; you can redistribute it and/or modify
10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as
11230557Sjimharris * published by the Free Software Foundation.
12230557Sjimharris *
13230557Sjimharris * This program is distributed in the hope that it will be useful, but
14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of
15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16230557Sjimharris * General Public License for more details.
17230557Sjimharris *
18230557Sjimharris * You should have received a copy of the GNU General Public License
19230557Sjimharris * along with this program; if not, write to the Free Software
20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21230557Sjimharris * The full GNU General Public License is included in this distribution
22230557Sjimharris * in the file called LICENSE.GPL.
23230557Sjimharris *
24230557Sjimharris * BSD LICENSE
25230557Sjimharris *
26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27230557Sjimharris * All rights reserved.
28230557Sjimharris *
29230557Sjimharris * Redistribution and use in source and binary forms, with or without
30230557Sjimharris * modification, are permitted provided that the following conditions
31230557Sjimharris * are met:
32230557Sjimharris *
33230557Sjimharris *   * Redistributions of source code must retain the above copyright
34230557Sjimharris *     notice, this list of conditions and the following disclaimer.
35230557Sjimharris *   * Redistributions in binary form must reproduce the above copyright
36230557Sjimharris *     notice, this list of conditions and the following disclaimer in
37230557Sjimharris *     the documentation and/or other materials provided with the
38230557Sjimharris *     distribution.
39230557Sjimharris *
40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51230557Sjimharris */
52230557Sjimharris
53230557Sjimharris#include <sys/cdefs.h>
54230557Sjimharris__FBSDID("$FreeBSD$");
55230557Sjimharris
56230557Sjimharris#include <dev/isci/scil/intel_sat.h>
57230557Sjimharris#include <dev/isci/scil/intel_sata.h>
58230557Sjimharris#include <dev/isci/scil/sci_types.h>
59230557Sjimharris#include <dev/isci/scil/scic_remote_device.h>
60230557Sjimharris#include <dev/isci/scil/scic_user_callback.h>
61230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h>
62230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h>
63230557Sjimharris#include <dev/isci/scil/scic_sds_stp_request.h>
64230557Sjimharris#include <dev/isci/scil/scic_sds_stp_pio_request.h>
65230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h>
66230557Sjimharris#include <dev/isci/sci_environment.h>
67230557Sjimharris#include <dev/isci/scil/sci_base_state_machine.h>
68230557Sjimharris#include <dev/isci/scil/scu_task_context.h>
69230557Sjimharris#include <dev/isci/scil/intel_ata.h>
70230557Sjimharris#include <dev/isci/scil/sci_util.h>
71230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h>
72230557Sjimharris#include <dev/isci/scil/scic_sds_request.h>
73230557Sjimharris#include <dev/isci/scil/scic_sds_stp_request.h>
74230557Sjimharris#include <dev/isci/scil/scu_completion_codes.h>
75230557Sjimharris#include <dev/isci/scil/scu_event_codes.h>
76230557Sjimharris#include <dev/isci/scil/sci_base_state.h>
77230557Sjimharris#include <dev/isci/scil/scic_sds_unsolicited_frame_control.h>
78230557Sjimharris#include <dev/isci/scil/scic_io_request.h>
79230557Sjimharris
80230557Sjimharris#if !defined(DISABLE_ATAPI)
81230557Sjimharris#include <dev/isci/scil/scic_sds_stp_packet_request.h>
82230557Sjimharris#endif
83230557Sjimharris
84230557Sjimharris/**
85230557Sjimharris * This macro returns the address of the stp h2d reg fis buffer in the io
86230557Sjimharris * request memory
87230557Sjimharris */
88230557Sjimharris#define scic_sds_stp_request_get_h2d_reg_buffer_unaligned(memory) \
89230557Sjimharris   ((SATA_FIS_REG_H2D_T *)( \
90230557Sjimharris      ((char *)(memory)) + sizeof(SCIC_SDS_STP_REQUEST_T) \
91230557Sjimharris   ))
92230557Sjimharris
93230557Sjimharris/**
94230557Sjimharris * This macro aligns the stp command buffer in DWORD alignment
95230557Sjimharris*/
96230557Sjimharris#define scic_sds_stp_request_align_h2d_reg_buffer(address) \
97230557Sjimharris   ((SATA_FIS_REG_H2D_T *)( \
98230557Sjimharris      (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \
99230557Sjimharris         & ~(sizeof(U32)- 1) \
100230557Sjimharris      ))
101230557Sjimharris
102230557Sjimharris/**
103230557Sjimharris * This macro returns the DWORD-aligned stp command buffer
104230557Sjimharris*/
105230557Sjimharris#define scic_sds_stp_request_get_h2d_reg_buffer(memory) \
106230557Sjimharris   ((SATA_FIS_REG_H2D_T *)  \
107230557Sjimharris       ((char *)scic_sds_stp_request_align_h2d_reg_buffer( \
108230557Sjimharris       (char *) scic_sds_stp_request_get_h2d_reg_buffer_unaligned(memory) \
109230557Sjimharris   )))
110230557Sjimharris
111230557Sjimharris/**
112230557Sjimharris * This macro returns the address of the stp response buffer in the io
113230557Sjimharris * request memory
114230557Sjimharris */
115230557Sjimharris#define scic_sds_stp_request_get_response_buffer_unaligned(memory) \
116230557Sjimharris   ((SATA_FIS_REG_D2H_T *)( \
117230557Sjimharris         ((char *)(scic_sds_stp_request_get_h2d_reg_buffer(memory))) \
118230557Sjimharris       + sizeof(SATA_FIS_REG_H2D_T) \
119230557Sjimharris   ))
120230557Sjimharris
121230557Sjimharris
122230557Sjimharris/**
123230557Sjimharris * This macro aligns the stp response buffer in DWORD alignment
124230557Sjimharris*/
125230557Sjimharris#define scic_sds_stp_request_align_response_buffer(address) \
126230557Sjimharris   ((SATA_FIS_REG_D2H_T *)( \
127230557Sjimharris      (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \
128230557Sjimharris         & ~(sizeof(U32)- 1) \
129230557Sjimharris   ))
130230557Sjimharris
131230557Sjimharris/**
132230557Sjimharris * This macro returns the DWORD-aligned stp response buffer
133230557Sjimharris*/
134230557Sjimharris#define scic_sds_stp_request_get_response_buffer(memory) \
135230557Sjimharris   ((SATA_FIS_REG_D2H_T *)  \
136230557Sjimharris      ((char *)scic_sds_stp_request_align_response_buffer( \
137230557Sjimharris         (char *)scic_sds_stp_request_get_response_buffer_unaligned(memory) \
138230557Sjimharris   )))
139230557Sjimharris
140230557Sjimharris
141230557Sjimharris/**
142230557Sjimharris * This macro returns the address of the task context buffer in the io
143230557Sjimharris * request memory
144230557Sjimharris */
145230557Sjimharris#define scic_sds_stp_request_get_task_context_buffer_unaligned(memory) \
146230557Sjimharris   ((SCU_TASK_CONTEXT_T *)( \
147230557Sjimharris        ((char *)(scic_sds_stp_request_get_response_buffer(memory))) \
148230557Sjimharris      + sizeof(SCI_SSP_RESPONSE_IU_T) \
149230557Sjimharris   ))
150230557Sjimharris
151230557Sjimharris/**
152230557Sjimharris * This macro returns the aligned task context buffer
153230557Sjimharris */
154230557Sjimharris#define scic_sds_stp_request_get_task_context_buffer(memory) \
155230557Sjimharris   ((SCU_TASK_CONTEXT_T *)( \
156230557Sjimharris      ((char *)scic_sds_request_align_task_context_buffer( \
157230557Sjimharris         (char *)scic_sds_stp_request_get_task_context_buffer_unaligned(memory)) \
158230557Sjimharris    )))
159230557Sjimharris
160230557Sjimharris/**
161230557Sjimharris * This macro returns the address of the sgl elment pairs in the io request
162230557Sjimharris * memory buffer
163230557Sjimharris */
164230557Sjimharris#define scic_sds_stp_request_get_sgl_element_buffer(memory) \
165230557Sjimharris   ((SCU_SGL_ELEMENT_PAIR_T *)( \
166230557Sjimharris        ((char *)(scic_sds_stp_request_get_task_context_buffer(memory))) \
167230557Sjimharris      + sizeof(SCU_TASK_CONTEXT_T) \
168230557Sjimharris    ))
169230557Sjimharris
170230557Sjimharris
171230557Sjimharris/**
172230557Sjimharris * This method return the memory space commonly required for STP IO and
173230557Sjimharris * task requests.
174230557Sjimharris *
175230557Sjimharris * @return U32
176230557Sjimharris */
177230557Sjimharrisstatic
178230557SjimharrisU32 scic_sds_stp_common_request_get_object_size(void)
179230557Sjimharris{
180230557Sjimharris   return   sizeof(SCIC_SDS_STP_REQUEST_T)
181230557Sjimharris          + sizeof(SATA_FIS_REG_H2D_T)
182230557Sjimharris          + sizeof(U32)
183230557Sjimharris          + sizeof(SATA_FIS_REG_D2H_T)
184230557Sjimharris          + sizeof(U32)
185230557Sjimharris          + sizeof(SCU_TASK_CONTEXT_T)
186230557Sjimharris          + CACHE_LINE_SIZE;
187230557Sjimharris}
188230557Sjimharris
189230557Sjimharris
190230557Sjimharris/**
191230557Sjimharris * This method return the memory space required for STP PIO requests.
192230557Sjimharris *
193230557Sjimharris * @return U32
194230557Sjimharris */
195230557SjimharrisU32 scic_sds_stp_request_get_object_size(void)
196230557Sjimharris{
197230557Sjimharris   return   scic_sds_stp_common_request_get_object_size()
198230557Sjimharris          + sizeof(SCU_SGL_ELEMENT_PAIR_T) * SCU_MAX_SGL_ELEMENT_PAIRS;
199230557Sjimharris}
200230557Sjimharris
201230557Sjimharris
202230557Sjimharris/**
203230557Sjimharris * This method return the memory space required for STP task requests.
204230557Sjimharris *
205230557Sjimharris * @return U32
206230557Sjimharris */
207230557SjimharrisU32 scic_sds_stp_task_request_get_object_size(void)
208230557Sjimharris{
209230557Sjimharris   return scic_sds_stp_common_request_get_object_size();
210230557Sjimharris}
211230557Sjimharris
212230557Sjimharris
213230557Sjimharris/**
214230557Sjimharris *
215230557Sjimharris *
216230557Sjimharris * @param[in] this_request
217230557Sjimharris */
218230557Sjimharrisvoid scic_sds_stp_request_assign_buffers(
219230557Sjimharris   SCIC_SDS_REQUEST_T * request
220230557Sjimharris)
221230557Sjimharris{
222230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
223230557Sjimharris
224230557Sjimharris   this_request->parent.command_buffer =
225230557Sjimharris      scic_sds_stp_request_get_h2d_reg_buffer(this_request);
226230557Sjimharris   this_request->parent.response_buffer =
227230557Sjimharris      scic_sds_stp_request_get_response_buffer(this_request);
228230557Sjimharris   this_request->parent.sgl_element_pair_buffer =
229230557Sjimharris      scic_sds_stp_request_get_sgl_element_buffer(this_request);
230230557Sjimharris   this_request->parent.sgl_element_pair_buffer =
231230557Sjimharris      scic_sds_request_align_sgl_element_buffer(this_request->parent.sgl_element_pair_buffer);
232230557Sjimharris
233230557Sjimharris   if (this_request->parent.was_tag_assigned_by_user == FALSE)
234230557Sjimharris   {
235230557Sjimharris      this_request->parent.task_context_buffer =
236230557Sjimharris         scic_sds_stp_request_get_task_context_buffer(this_request);
237230557Sjimharris   }
238230557Sjimharris}
239230557Sjimharris
240230557Sjimharris/**
241230557Sjimharris * @brief This method is will fill in the SCU Task Context for any type of
242230557Sjimharris *        SATA request.  This is called from the various SATA constructors.
243230557Sjimharris *
244230557Sjimharris * @pre The general io request construction is complete.
245230557Sjimharris * @pre The buffer assignment for the command buffer is complete.
246230557Sjimharris *
247230557Sjimharris * @param[in] this_request The general IO request object which is to be used
248230557Sjimharris *       in constructing the SCU task context.
249230557Sjimharris * @param[in] task_context The buffer pointer for the SCU task context which
250230557Sjimharris *       is being constructed.
251230557Sjimharris *
252230557Sjimharris * @return none
253230557Sjimharris *
254230557Sjimharris * @todo Revisit task context construction to determine what is common for
255230557Sjimharris *       SSP/SMP/STP task context structures.
256230557Sjimharris */
257230557Sjimharrisvoid scu_sata_reqeust_construct_task_context(
258230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
259230557Sjimharris   SCU_TASK_CONTEXT_T * task_context
260230557Sjimharris)
261230557Sjimharris{
262230557Sjimharris   SCI_PHYSICAL_ADDRESS      physical_address;
263230557Sjimharris   SCIC_SDS_CONTROLLER_T    *owning_controller;
264230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T *target_device;
265230557Sjimharris   SCIC_SDS_PORT_T          *target_port;
266230557Sjimharris
267230557Sjimharris   owning_controller = scic_sds_request_get_controller(this_request);
268230557Sjimharris   target_device = scic_sds_request_get_device(this_request);
269230557Sjimharris   target_port = scic_sds_request_get_port(this_request);
270230557Sjimharris
271230557Sjimharris   // Fill in the TC with the its required data
272230557Sjimharris   task_context->abort = 0;
273230557Sjimharris   task_context->priority = SCU_TASK_PRIORITY_NORMAL;
274230557Sjimharris   task_context->initiator_request = 1;
275230557Sjimharris   task_context->connection_rate =
276230557Sjimharris      scic_remote_device_get_connection_rate(target_device);
277230557Sjimharris   task_context->protocol_engine_index =
278230557Sjimharris      scic_sds_controller_get_protocol_engine_group(owning_controller);
279230557Sjimharris   task_context->logical_port_index =
280230557Sjimharris      scic_sds_port_get_index(target_port);
281230557Sjimharris   task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP;
282230557Sjimharris   task_context->valid = SCU_TASK_CONTEXT_VALID;
283230557Sjimharris   task_context->context_type = SCU_TASK_CONTEXT_TYPE;
284230557Sjimharris
285230557Sjimharris   task_context->remote_node_index =
286230557Sjimharris      scic_sds_remote_device_get_index(this_request->target_device);
287230557Sjimharris   task_context->command_code = 0;
288230557Sjimharris
289230557Sjimharris   task_context->link_layer_control = 0;
290230557Sjimharris   task_context->do_not_dma_ssp_good_response = 1;
291230557Sjimharris   task_context->strict_ordering = 0;
292230557Sjimharris   task_context->control_frame = 0;
293230557Sjimharris   task_context->timeout_enable = 0;
294230557Sjimharris   task_context->block_guard_enable = 0;
295230557Sjimharris
296230557Sjimharris   task_context->address_modifier = 0;
297230557Sjimharris   task_context->task_phase = 0x01;
298230557Sjimharris
299230557Sjimharris   task_context->ssp_command_iu_length =
300230557Sjimharris      (sizeof(SATA_FIS_REG_H2D_T) - sizeof(U32)) / sizeof(U32);
301230557Sjimharris
302230557Sjimharris   // Set the first word of the H2D REG FIS
303230557Sjimharris   task_context->type.words[0] = *(U32 *)this_request->command_buffer;
304230557Sjimharris
305230557Sjimharris   if (this_request->was_tag_assigned_by_user)
306230557Sjimharris   {
307230557Sjimharris      // Build the task context now since we have already read the data
308230557Sjimharris      this_request->post_context = (
309230557Sjimharris           SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
310230557Sjimharris         | (
311230557Sjimharris                scic_sds_controller_get_protocol_engine_group(owning_controller)
312230557Sjimharris             << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
313230557Sjimharris           )
314230557Sjimharris         | (
315230557Sjimharris                 scic_sds_port_get_index(target_port)
316230557Sjimharris              << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
317230557Sjimharris           )
318230557Sjimharris         | scic_sds_io_tag_get_index(this_request->io_tag)
319230557Sjimharris      );
320230557Sjimharris   }
321230557Sjimharris   else
322230557Sjimharris   {
323230557Sjimharris      // Build the task context now since we have already read the data
324230557Sjimharris      this_request->post_context = (
325230557Sjimharris           SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
326230557Sjimharris         | (
327230557Sjimharris               scic_sds_controller_get_protocol_engine_group(owning_controller)
328230557Sjimharris            << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
329230557Sjimharris           )
330230557Sjimharris         | (
331230557Sjimharris                scic_sds_port_get_index(target_port)
332230557Sjimharris             << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
333230557Sjimharris           )
334230557Sjimharris         // This is not assigned because we have to wait until we get a TCi
335230557Sjimharris      );
336230557Sjimharris   }
337230557Sjimharris
338230557Sjimharris   // Copy the physical address for the command buffer to the SCU Task Context
339230557Sjimharris   // We must offset the command buffer by 4 bytes because the first 4 bytes are
340230557Sjimharris   // transfered in the body of the TC
341230557Sjimharris   scic_cb_io_request_get_physical_address(
342230557Sjimharris      scic_sds_request_get_controller(this_request),
343230557Sjimharris      this_request,
344230557Sjimharris      ((char *)this_request->command_buffer) + sizeof(U32),
345230557Sjimharris      &physical_address
346230557Sjimharris   );
347230557Sjimharris
348230557Sjimharris   task_context->command_iu_upper =
349230557Sjimharris      sci_cb_physical_address_upper(physical_address);
350230557Sjimharris   task_context->command_iu_lower =
351230557Sjimharris      sci_cb_physical_address_lower(physical_address);
352230557Sjimharris
353230557Sjimharris   // SATA Requests do not have a response buffer
354230557Sjimharris   task_context->response_iu_upper = 0;
355230557Sjimharris   task_context->response_iu_lower = 0;
356230557Sjimharris}
357230557Sjimharris
358230557Sjimharris/**
359230557Sjimharris * This method will perform any general sata request construction.
360230557Sjimharris *
361230557Sjimharris * @todo What part of SATA IO request construction is general?
362230557Sjimharris *
363230557Sjimharris * @param[in] this_request
364230557Sjimharris *
365230557Sjimharris * @return none
366230557Sjimharris */
367230557Sjimharrisvoid scic_sds_stp_non_ncq_request_construct(
368230557Sjimharris   SCIC_SDS_REQUEST_T * this_request
369230557Sjimharris)
370230557Sjimharris{
371230557Sjimharris   this_request->has_started_substate_machine = TRUE;
372230557Sjimharris}
373230557Sjimharris
374230557Sjimharris/**
375230557Sjimharris * This method will perform request construction common to all types of
376230557Sjimharris * STP requests that are optimized by the silicon (i.e. UDMA, NCQ).
377230557Sjimharris *
378230557Sjimharris * @param[in,out] this_request This parameter specifies the request to be
379230557Sjimharris *                constructed as an optimized request.
380230557Sjimharris * @param[in] optimized_task_type This parameter specifies whether the
381230557Sjimharris *            request is to be an UDMA request or a NCQ request.
382230557Sjimharris *            - A value of 0 indicates UDMA.
383230557Sjimharris *            - A value of 1 indicates NCQ.
384230557Sjimharris *
385230557Sjimharris * @return This method returns an indication as to whether the construction
386230557Sjimharris *         was successful.
387230557Sjimharris */
388230557Sjimharrisstatic
389230557Sjimharrisvoid scic_sds_stp_optimized_request_construct(
390230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
391230557Sjimharris   U8                   optimized_task_type,
392230557Sjimharris   U32                  transfer_length,
393230557Sjimharris   SCI_IO_REQUEST_DATA_DIRECTION data_direction
394230557Sjimharris)
395230557Sjimharris{
396230557Sjimharris   SCU_TASK_CONTEXT_T * task_context = this_request->task_context_buffer;
397230557Sjimharris
398230557Sjimharris   // Build the STP task context structure
399230557Sjimharris   scu_sata_reqeust_construct_task_context(this_request, task_context);
400230557Sjimharris
401230557Sjimharris   // Copy over the number of bytes to be transfered
402230557Sjimharris   task_context->transfer_length_bytes = transfer_length;
403230557Sjimharris
404230557Sjimharris   if ( data_direction == SCI_IO_REQUEST_DATA_OUT )
405230557Sjimharris   {
406230557Sjimharris      // The difference between the DMA IN and DMA OUT request task type
407230557Sjimharris      // values are consistent with the difference between FPDMA READ
408230557Sjimharris      // and FPDMA WRITE values.  Add the supplied task type parameter
409230557Sjimharris      // to this difference to set the task type properly for this
410230557Sjimharris      // DATA OUT (WRITE) case.
411230557Sjimharris      task_context->task_type = optimized_task_type + (SCU_TASK_TYPE_DMA_OUT
412230557Sjimharris                                                     - SCU_TASK_TYPE_DMA_IN);
413230557Sjimharris   }
414230557Sjimharris   else
415230557Sjimharris   {
416230557Sjimharris      // For the DATA IN (READ) case, simply save the supplied
417230557Sjimharris      // optimized task type.
418230557Sjimharris      task_context->task_type = optimized_task_type;
419230557Sjimharris   }
420230557Sjimharris}
421230557Sjimharris
422230557Sjimharris/**
423230557Sjimharris * This method performs the operations common to all SATA/STP requests
424230557Sjimharris * utilizing the raw frame method.
425230557Sjimharris *
426230557Sjimharris * @param[in] this_request This parameter specifies the STP request object
427230557Sjimharris *            for which to construct a RAW command frame task context.
428230557Sjimharris * @param[in] task_context This parameter specifies the SCU specific
429230557Sjimharris *            task context buffer to construct.
430230557Sjimharris *
431230557Sjimharris * @return none
432230557Sjimharris */
433230557Sjimharrisvoid scu_stp_raw_request_construct_task_context(
434230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request,
435230557Sjimharris   SCU_TASK_CONTEXT_T     * task_context
436230557Sjimharris)
437230557Sjimharris{
438230557Sjimharris   scu_sata_reqeust_construct_task_context(&this_request->parent, task_context);
439230557Sjimharris
440230557Sjimharris   task_context->control_frame         = 0;
441230557Sjimharris   task_context->priority              = SCU_TASK_PRIORITY_NORMAL;
442230557Sjimharris   task_context->task_type             = SCU_TASK_TYPE_SATA_RAW_FRAME;
443230557Sjimharris   task_context->type.stp.fis_type     = SATA_FIS_TYPE_REGH2D;
444230557Sjimharris   task_context->transfer_length_bytes = sizeof(SATA_FIS_REG_H2D_T) - sizeof(U32);
445230557Sjimharris}
446230557Sjimharris
447230557Sjimharris/**
448230557Sjimharris * This method will construct the STP Non-data request and its associated
449230557Sjimharris * TC data.  A non-data request essentially behaves like a 0 length read
450230557Sjimharris * request in the SCU.
451230557Sjimharris *
452230557Sjimharris * @param[in] this_request This parameter specifies the core request
453230557Sjimharris *            object to construction into an STP/SATA non-data request.
454230557Sjimharris *
455230557Sjimharris * @return This method currently always returns SCI_SUCCESS
456230557Sjimharris */
457230557SjimharrisSCI_STATUS scic_sds_stp_non_data_request_construct(
458230557Sjimharris   SCIC_SDS_REQUEST_T * this_request
459230557Sjimharris)
460230557Sjimharris{
461230557Sjimharris   scic_sds_stp_non_ncq_request_construct(this_request);
462230557Sjimharris
463230557Sjimharris   // Build the STP task context structure
464230557Sjimharris   scu_stp_raw_request_construct_task_context(
465230557Sjimharris      (SCIC_SDS_STP_REQUEST_T*) this_request,
466230557Sjimharris      this_request->task_context_buffer
467230557Sjimharris   );
468230557Sjimharris
469230557Sjimharris   sci_base_state_machine_construct(
470230557Sjimharris      &this_request->started_substate_machine,
471230557Sjimharris      &this_request->parent.parent,
472230557Sjimharris      scic_sds_stp_request_started_non_data_substate_table,
473230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
474230557Sjimharris   );
475230557Sjimharris
476230557Sjimharris   return SCI_SUCCESS;
477230557Sjimharris}
478230557Sjimharris
479230557Sjimharris
480230557SjimharrisSCI_STATUS scic_sds_stp_soft_reset_request_construct(
481230557Sjimharris   SCIC_SDS_REQUEST_T * this_request
482230557Sjimharris)
483230557Sjimharris{
484230557Sjimharris   scic_sds_stp_non_ncq_request_construct(this_request);
485230557Sjimharris
486230557Sjimharris   // Build the STP task context structure
487230557Sjimharris   scu_stp_raw_request_construct_task_context(
488230557Sjimharris      (SCIC_SDS_STP_REQUEST_T*) this_request,
489230557Sjimharris      this_request->task_context_buffer
490230557Sjimharris   );
491230557Sjimharris
492230557Sjimharris   sci_base_state_machine_construct(
493230557Sjimharris      &this_request->started_substate_machine,
494230557Sjimharris      &this_request->parent.parent,
495230557Sjimharris      scic_sds_stp_request_started_soft_reset_substate_table,
496230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
497230557Sjimharris   );
498230557Sjimharris
499230557Sjimharris   return SCI_SUCCESS;
500230557Sjimharris}
501230557Sjimharris
502230557Sjimharris/**
503230557Sjimharris * @brief This method constructs the SATA request object.
504230557Sjimharris *
505230557Sjimharris * @param[in] this_request
506230557Sjimharris * @param[in] sat_protocol
507230557Sjimharris * @param[in] transfer_length
508230557Sjimharris * @param[in] data_direction
509230557Sjimharris * @param[in] copy_rx_frame
510230557Sjimharris * @param[in] do_translate_sgl This parameter specifies whether SGL
511230557Sjimharris *            translation should be performed or if the user is handling
512230557Sjimharris *            it.
513230557Sjimharris *
514230557Sjimharris * @return SCI_STATUS
515230557Sjimharris */
516230557SjimharrisSCI_STATUS scic_sds_io_request_construct_sata(
517230557Sjimharris   SCIC_SDS_REQUEST_T          * this_request,
518230557Sjimharris   U8                            sat_protocol,
519230557Sjimharris   U32                           transfer_length,
520230557Sjimharris   SCI_IO_REQUEST_DATA_DIRECTION data_direction,
521230557Sjimharris   BOOL                          copy_rx_frame,
522230557Sjimharris   BOOL                          do_translate_sgl
523230557Sjimharris)
524230557Sjimharris{
525230557Sjimharris   SCI_STATUS  status = SCI_SUCCESS;
526230557Sjimharris
527230557Sjimharris   this_request->protocol = SCIC_STP_PROTOCOL;
528230557Sjimharris
529230557Sjimharris   this_request->sat_protocol = sat_protocol;
530230557Sjimharris
531230557Sjimharris   switch (sat_protocol)
532230557Sjimharris   {
533230557Sjimharris   case SAT_PROTOCOL_FPDMA:
534230557Sjimharris      scic_sds_stp_optimized_request_construct(
535230557Sjimharris         this_request,
536230557Sjimharris         SCU_TASK_TYPE_FPDMAQ_READ,
537230557Sjimharris         transfer_length,
538230557Sjimharris         data_direction
539230557Sjimharris      );
540230557Sjimharris
541230557Sjimharris      // Copy over the SGL elements
542230557Sjimharris      if (do_translate_sgl == TRUE)
543230557Sjimharris         scic_sds_request_build_sgl(this_request);
544230557Sjimharris   break;
545230557Sjimharris
546230557Sjimharris   case SAT_PROTOCOL_UDMA_DATA_IN:
547230557Sjimharris   case SAT_PROTOCOL_UDMA_DATA_OUT:
548230557Sjimharris      scic_sds_stp_non_ncq_request_construct(this_request);
549230557Sjimharris
550230557Sjimharris      scic_sds_stp_optimized_request_construct(
551230557Sjimharris         this_request, SCU_TASK_TYPE_DMA_IN, transfer_length, data_direction
552230557Sjimharris      );
553230557Sjimharris
554230557Sjimharris      // Copy over the SGL elements
555230557Sjimharris      if (do_translate_sgl == TRUE)
556230557Sjimharris         scic_sds_request_build_sgl(this_request);
557230557Sjimharris
558230557Sjimharris      sci_base_state_machine_construct(
559230557Sjimharris         &this_request->started_substate_machine,
560230557Sjimharris         &this_request->parent.parent,
561230557Sjimharris         scic_sds_stp_request_started_udma_substate_table,
562230557Sjimharris         SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
563230557Sjimharris      );
564230557Sjimharris   break;
565230557Sjimharris
566230557Sjimharris   case SAT_PROTOCOL_PIO_DATA_IN:
567230557Sjimharris   case SAT_PROTOCOL_PIO_DATA_OUT:
568230557Sjimharris      status = scic_sds_stp_pio_request_construct(
569230557Sjimharris                  this_request, sat_protocol, copy_rx_frame);
570230557Sjimharris   break;
571230557Sjimharris
572230557Sjimharris   case SAT_PROTOCOL_ATA_HARD_RESET:
573230557Sjimharris   case SAT_PROTOCOL_SOFT_RESET:
574230557Sjimharris      status = scic_sds_stp_soft_reset_request_construct(this_request);
575230557Sjimharris   break;
576230557Sjimharris
577230557Sjimharris   case SAT_PROTOCOL_NON_DATA:
578230557Sjimharris      status = scic_sds_stp_non_data_request_construct(this_request);
579230557Sjimharris   break;
580230557Sjimharris
581230557Sjimharris#if !defined(DISABLE_ATAPI)
582230557Sjimharris   case SAT_PROTOCOL_PACKET_NON_DATA:
583230557Sjimharris   case SAT_PROTOCOL_PACKET_DMA_DATA_IN:
584230557Sjimharris   case SAT_PROTOCOL_PACKET_DMA_DATA_OUT:
585230557Sjimharris   case SAT_PROTOCOL_PACKET_PIO_DATA_IN:
586230557Sjimharris   case SAT_PROTOCOL_PACKET_PIO_DATA_OUT:
587230557Sjimharris      status = scic_sds_stp_packet_request_construct(this_request);
588230792Sjimharris      if (do_translate_sgl == TRUE)
589230792Sjimharris         scic_sds_request_build_sgl(this_request);
590230557Sjimharris   break;
591230557Sjimharris#endif
592230557Sjimharris
593230557Sjimharris   case SAT_PROTOCOL_DMA_QUEUED:
594230557Sjimharris   case SAT_PROTOCOL_DMA:
595230557Sjimharris   case SAT_PROTOCOL_DEVICE_DIAGNOSTIC:
596230557Sjimharris   case SAT_PROTOCOL_DEVICE_RESET:
597230557Sjimharris   case SAT_PROTOCOL_RETURN_RESPONSE_INFO:
598230557Sjimharris   default:
599230557Sjimharris      SCIC_LOG_ERROR((
600230557Sjimharris         sci_base_object_get_logger(this_request),
601230557Sjimharris         SCIC_LOG_OBJECT_STP_IO_REQUEST,
602230557Sjimharris         "SCIC IO Request 0x%x received un-handled SAT Protocol %d.\n",
603230557Sjimharris         this_request, sat_protocol
604230557Sjimharris      ));
605230557Sjimharris
606230557Sjimharris      status = SCI_FAILURE;
607230557Sjimharris   break;
608230557Sjimharris   }
609230557Sjimharris
610230557Sjimharris   if (status == SCI_SUCCESS)
611230557Sjimharris   {
612230557Sjimharris      scic_sds_request_initialize_state_logging(this_request);
613230557Sjimharris
614230557Sjimharris      sci_base_state_machine_change_state(
615230557Sjimharris         &this_request->parent.state_machine,
616230557Sjimharris         SCI_BASE_REQUEST_STATE_CONSTRUCTED
617230557Sjimharris      );
618230557Sjimharris   }
619230557Sjimharris
620230557Sjimharris   return status;
621230557Sjimharris}
622230557Sjimharris
623230557Sjimharris//****************************************************************************
624230557Sjimharris//* SCIC Interface Implementation
625230557Sjimharris//****************************************************************************
626230557Sjimharris
627230557Sjimharrisvoid scic_stp_io_request_set_ncq_tag(
628230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  scic_io_request,
629230557Sjimharris   U16                      ncq_tag
630230557Sjimharris)
631230557Sjimharris{
632230557Sjimharris   /**
633230557Sjimharris    * @note This could be made to return an error to the user if the user
634230557Sjimharris    *       attempts to set the NCQ tag in the wrong state.
635230557Sjimharris    */
636230557Sjimharris   SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request;
637230557Sjimharris   this_request->task_context_buffer->type.stp.ncq_tag = ncq_tag;
638230557Sjimharris}
639230557Sjimharris
640230557Sjimharris// ---------------------------------------------------------------------------
641230557Sjimharris
642230557Sjimharrisvoid * scic_stp_io_request_get_h2d_reg_address(
643230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  scic_io_request
644230557Sjimharris)
645230557Sjimharris{
646230557Sjimharris   SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request;
647230557Sjimharris
648230557Sjimharris   return this_request->command_buffer;
649230557Sjimharris}
650230557Sjimharris
651230557Sjimharris// ---------------------------------------------------------------------------
652230557Sjimharris
653230557Sjimharrisvoid * scic_stp_io_request_get_d2h_reg_address(
654230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  scic_io_request
655230557Sjimharris)
656230557Sjimharris{
657230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)scic_io_request;
658230557Sjimharris
659230557Sjimharris   return &this_request->d2h_reg_fis;
660230557Sjimharris}
661230557Sjimharris
662230557Sjimharris/**
663230557Sjimharris * Get the next SGL element from the request.
664230557Sjimharris *    - Check on which SGL element pair we are working
665230557Sjimharris *    - if working on SLG pair element A
666230557Sjimharris *       - advance to element B
667230557Sjimharris *    - else
668230557Sjimharris *       - check to see if there are more SGL element pairs
669230557Sjimharris *           for this IO request
670230557Sjimharris *       - if there are more SGL element pairs
671230557Sjimharris *          - advance to the next pair and return element A
672230557Sjimharris *
673230557Sjimharris * @param[in] this_request
674230557Sjimharris *
675230557Sjimharris * @return SCU_SGL_ELEMENT_T*
676230557Sjimharris */
677230557SjimharrisSCU_SGL_ELEMENT_T * scic_sds_stp_request_pio_get_next_sgl(
678230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request
679230557Sjimharris)
680230557Sjimharris{
681230557Sjimharris   SCU_SGL_ELEMENT_T * current_sgl;
682230557Sjimharris
683230557Sjimharris   if (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A)
684230557Sjimharris   {
685230557Sjimharris      if (
686230557Sjimharris            (this_request->type.pio.request_current.sgl_pair->B.address_lower == 0)
687230557Sjimharris         && (this_request->type.pio.request_current.sgl_pair->B.address_upper == 0)
688230557Sjimharris         )
689230557Sjimharris      {
690230557Sjimharris         current_sgl = NULL;
691230557Sjimharris      }
692230557Sjimharris      else
693230557Sjimharris      {
694230557Sjimharris         this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_B;
695230557Sjimharris         current_sgl = &(this_request->type.pio.request_current.sgl_pair->B);
696230557Sjimharris      }
697230557Sjimharris   }
698230557Sjimharris   else
699230557Sjimharris   {
700230557Sjimharris      if (
701230557Sjimharris            (this_request->type.pio.request_current.sgl_pair->next_pair_lower == 0)
702230557Sjimharris         && (this_request->type.pio.request_current.sgl_pair->next_pair_upper == 0)
703230557Sjimharris         )
704230557Sjimharris      {
705230557Sjimharris         current_sgl = NULL;
706230557Sjimharris      }
707230557Sjimharris      else
708230557Sjimharris      {
709230557Sjimharris         this_request->type.pio.request_current.sgl_pair =
710230557Sjimharris            scic_sds_request_get_sgl_element_pair(
711230557Sjimharris               &(this_request->parent),
712230557Sjimharris               ++this_request->type.pio.sgl_pair_index
713230557Sjimharris            );
714230557Sjimharris
715230557Sjimharris         this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A;
716230557Sjimharris
717230557Sjimharris         current_sgl = &(this_request->type.pio.request_current.sgl_pair->A);
718230557Sjimharris      }
719230557Sjimharris   }
720230557Sjimharris
721230557Sjimharris   return current_sgl;
722230557Sjimharris}
723230557Sjimharris
724230557Sjimharris/**
725230557Sjimharris * This method will construct the SATA PIO request.
726230557Sjimharris *
727230557Sjimharris * @param[in] scic_io_request The core request object which is cast to a SATA
728230557Sjimharris *            PIO request object.
729230557Sjimharris *
730230557Sjimharris * @return This method returns an indication as to whether the construction
731230557Sjimharris *         was successful.
732230557Sjimharris * @retval SCI_SUCCESS Currently this method always returns this value.
733230557Sjimharris */
734230557SjimharrisSCI_STATUS scic_sds_stp_pio_request_construct(
735230557Sjimharris   SCIC_SDS_REQUEST_T  * scic_io_request,
736230557Sjimharris   U8                    sat_protocol,
737230557Sjimharris   BOOL                  copy_rx_frame
738230557Sjimharris)
739230557Sjimharris{
740230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request;
741230557Sjimharris
742230557Sjimharris   this_request = (SCIC_SDS_STP_REQUEST_T *)scic_io_request;
743230557Sjimharris
744230557Sjimharris   scic_sds_stp_non_ncq_request_construct(&this_request->parent);
745230557Sjimharris
746230557Sjimharris   scu_stp_raw_request_construct_task_context(
747230557Sjimharris      this_request, this_request->parent.task_context_buffer
748230557Sjimharris   );
749230557Sjimharris
750230557Sjimharris   this_request->type.pio.current_transfer_bytes = 0;
751230557Sjimharris   this_request->type.pio.ending_error = 0;
752230557Sjimharris   this_request->type.pio.ending_status = 0;
753230557Sjimharris
754230557Sjimharris   this_request->type.pio.request_current.sgl_offset = 0;
755230557Sjimharris   this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A;
756230557Sjimharris   this_request->type.pio.sat_protocol = sat_protocol;
757230557Sjimharris   this_request->type.pio.sgl_pair_index = 0;
758230557Sjimharris
759230557Sjimharris   if ((copy_rx_frame) || (sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT))
760230557Sjimharris   {
761230557Sjimharris      scic_sds_request_build_sgl(&this_request->parent);
762230557Sjimharris      // Since the IO request copy of the TC contains the same data as
763230557Sjimharris      // the actual TC this pointer is vaild for either.
764230557Sjimharris      this_request->type.pio.request_current.sgl_pair =
765230557Sjimharris         &this_request->parent.task_context_buffer->sgl_pair_ab;
766230557Sjimharris   }
767230557Sjimharris   else
768230557Sjimharris   {
769230557Sjimharris      // The user does not want the data copied to the SGL buffer location
770230557Sjimharris      this_request->type.pio.request_current.sgl_pair = NULL;
771230557Sjimharris   }
772230557Sjimharris
773230557Sjimharris   sci_base_state_machine_construct(
774230557Sjimharris      &this_request->parent.started_substate_machine,
775230557Sjimharris      &this_request->parent.parent.parent,
776230557Sjimharris      scic_sds_stp_request_started_pio_substate_table,
777230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
778230557Sjimharris   );
779230557Sjimharris
780230557Sjimharris   return SCI_SUCCESS;
781230557Sjimharris}
782230557Sjimharris
783230557Sjimharris//******************************************************************************
784230557Sjimharris//* STP NON-DATA STATE MACHINE
785230557Sjimharris//******************************************************************************
786230557Sjimharris
787230557Sjimharris/**
788230557Sjimharris * This method processes a TC completion.  The expected TC completion is
789230557Sjimharris * for the transmission of the H2D register FIS containing the SATA/STP
790230557Sjimharris * non-data request.
791230557Sjimharris *
792230557Sjimharris * @param[in] this_request
793230557Sjimharris * @param[in] completion_code
794230557Sjimharris *
795230557Sjimharris * @return This method always successfully processes the TC completion.
796230557Sjimharris * @retval SCI_SUCCESS This value is always returned.
797230557Sjimharris */
798230557Sjimharrisstatic
799230557SjimharrisSCI_STATUS scic_sds_stp_request_non_data_await_h2d_tc_completion_handler(
800230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
801230557Sjimharris   U32                  completion_code
802230557Sjimharris)
803230557Sjimharris{
804230557Sjimharris   SCIC_LOG_TRACE((
805230557Sjimharris      sci_base_object_get_logger(this_request),
806230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
807230557Sjimharris      "scic_sds_stp_request_non_data_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n",
808230557Sjimharris      this_request, completion_code
809230557Sjimharris   ));
810230557Sjimharris
811230557Sjimharris   switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
812230557Sjimharris   {
813230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
814230557Sjimharris      scic_sds_request_set_status(
815230557Sjimharris         this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
816230557Sjimharris      );
817230557Sjimharris
818230557Sjimharris      sci_base_state_machine_change_state(
819230557Sjimharris         &this_request->started_substate_machine,
820230557Sjimharris         SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
821230557Sjimharris      );
822230557Sjimharris      break;
823230557Sjimharris
824230557Sjimharris   default:
825230557Sjimharris      // All other completion status cause the IO to be complete.  If a NAK
826230557Sjimharris      // was received, then it is up to the user to retry the request.
827230557Sjimharris      scic_sds_request_set_status(
828230557Sjimharris         this_request,
829230557Sjimharris         SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
830230557Sjimharris         SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
831230557Sjimharris      );
832230557Sjimharris
833230557Sjimharris      sci_base_state_machine_change_state(
834230557Sjimharris         &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
835230557Sjimharris      );
836230557Sjimharris      break;
837230557Sjimharris   }
838230557Sjimharris
839230557Sjimharris   return SCI_SUCCESS;
840230557Sjimharris}
841230557Sjimharris
842230557Sjimharris/**
843230557Sjimharris * This method processes frames received from the target while waiting
844230557Sjimharris * for a device to host register FIS.  If a non-register FIS is received
845230557Sjimharris * during this time, it is treated as a protocol violation from an
846230557Sjimharris * IO perspective.
847230557Sjimharris *
848230557Sjimharris * @param[in] request This parameter specifies the request for which a
849230557Sjimharris *            frame has been received.
850230557Sjimharris * @param[in] frame_index This parameter specifies the index of the frame
851230557Sjimharris *            that has been received.
852230557Sjimharris *
853230557Sjimharris * @return Indicate if the received frame was processed successfully.
854230557Sjimharris */
855230557Sjimharrisstatic
856230557SjimharrisSCI_STATUS scic_sds_stp_request_non_data_await_d2h_frame_handler(
857230557Sjimharris   SCIC_SDS_REQUEST_T * request,
858230557Sjimharris   U32                  frame_index
859230557Sjimharris)
860230557Sjimharris{
861230557Sjimharris   SCI_STATUS               status;
862230557Sjimharris   SATA_FIS_HEADER_T      * frame_header;
863230557Sjimharris   U32                    * frame_buffer;
864230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
865230557Sjimharris
866230557Sjimharris   // Save off the controller, so that we do not touch the request after it
867230557Sjimharris   //  is completed.
868230557Sjimharris   SCIC_SDS_CONTROLLER_T  * owning_controller = this_request->parent.owning_controller;
869230557Sjimharris
870230557Sjimharris   SCIC_LOG_TRACE((
871230557Sjimharris      sci_base_object_get_logger(this_request),
872230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
873230557Sjimharris      "scic_sds_stp_request_non_data_await_d2h_frame_handler(0x%x, 0x%x) enter\n",
874230557Sjimharris      this_request, frame_index
875230557Sjimharris   ));
876230557Sjimharris
877230557Sjimharris   status = scic_sds_unsolicited_frame_control_get_header(
878230557Sjimharris               &(owning_controller->uf_control),
879230557Sjimharris               frame_index,
880230557Sjimharris               (void**) &frame_header
881230557Sjimharris            );
882230557Sjimharris
883230557Sjimharris   if (status == SCI_SUCCESS)
884230557Sjimharris   {
885230557Sjimharris      switch (frame_header->fis_type)
886230557Sjimharris      {
887230557Sjimharris      case SATA_FIS_TYPE_REGD2H:
888230557Sjimharris         scic_sds_unsolicited_frame_control_get_buffer(
889230557Sjimharris            &(owning_controller->uf_control),
890230557Sjimharris            frame_index,
891230557Sjimharris            (void**) &frame_buffer
892230557Sjimharris         );
893230557Sjimharris
894230557Sjimharris         scic_sds_controller_copy_sata_response(
895230557Sjimharris            &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer
896230557Sjimharris         );
897230557Sjimharris
898230557Sjimharris         // The command has completed with error
899230557Sjimharris         scic_sds_request_set_status(
900230557Sjimharris            &this_request->parent,
901230557Sjimharris            SCU_TASK_DONE_CHECK_RESPONSE,
902230557Sjimharris            SCI_FAILURE_IO_RESPONSE_VALID
903230557Sjimharris         );
904230557Sjimharris         break;
905230557Sjimharris
906230557Sjimharris      default:
907230557Sjimharris         SCIC_LOG_WARNING((
908230557Sjimharris            sci_base_object_get_logger(this_request),
909230557Sjimharris            SCIC_LOG_OBJECT_STP_IO_REQUEST,
910230557Sjimharris            "IO Request:0x%x Frame Id:%d protocol violation occurred\n",
911230557Sjimharris            this_request, frame_index
912230557Sjimharris         ));
913230557Sjimharris
914230557Sjimharris         scic_sds_request_set_status(
915230557Sjimharris            &this_request->parent,
916230557Sjimharris            SCU_TASK_DONE_UNEXP_FIS,
917230557Sjimharris            SCI_FAILURE_PROTOCOL_VIOLATION
918230557Sjimharris         );
919230557Sjimharris         break;
920230557Sjimharris      }
921230557Sjimharris
922230557Sjimharris      sci_base_state_machine_change_state(
923230557Sjimharris         &this_request->parent.parent.state_machine,
924230557Sjimharris         SCI_BASE_REQUEST_STATE_COMPLETED
925230557Sjimharris      );
926230557Sjimharris
927230557Sjimharris      // Frame has been decoded return it to the controller
928230557Sjimharris      scic_sds_controller_release_frame(
929230557Sjimharris         owning_controller, frame_index
930230557Sjimharris      );
931230557Sjimharris   }
932230557Sjimharris   else
933230557Sjimharris   {
934230557Sjimharris      SCIC_LOG_ERROR((
935230557Sjimharris         sci_base_object_get_logger(this_request),
936230557Sjimharris         SCIC_LOG_OBJECT_STP_IO_REQUEST,
937230557Sjimharris         "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
938230557Sjimharris         this_request, frame_index, status
939230557Sjimharris      ));
940230557Sjimharris   }
941230557Sjimharris
942230557Sjimharris   return status;
943230557Sjimharris}
944230557Sjimharris
945230557Sjimharris// ---------------------------------------------------------------------------
946230557Sjimharris
947230557SjimharrisSCIC_SDS_IO_REQUEST_STATE_HANDLER_T
948230557Sjimharris   scic_sds_stp_request_started_non_data_substate_handler_table
949230557Sjimharris      [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_MAX_SUBSTATES] =
950230557Sjimharris{
951230557Sjimharris   // SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
952230557Sjimharris   {
953230557Sjimharris      {
954230557Sjimharris         scic_sds_request_default_start_handler,
955230557Sjimharris         scic_sds_request_started_state_abort_handler,
956230557Sjimharris         scic_sds_request_default_complete_handler,
957230557Sjimharris         scic_sds_request_default_destruct_handler
958230557Sjimharris      },
959230557Sjimharris      scic_sds_stp_request_non_data_await_h2d_tc_completion_handler,
960230557Sjimharris      scic_sds_request_default_event_handler,
961230557Sjimharris      scic_sds_request_default_frame_handler
962230557Sjimharris   },
963230557Sjimharris   // SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
964230557Sjimharris   {
965230557Sjimharris      {
966230557Sjimharris         scic_sds_request_default_start_handler,
967230557Sjimharris         scic_sds_request_started_state_abort_handler,
968230557Sjimharris         scic_sds_request_default_complete_handler,
969230557Sjimharris         scic_sds_request_default_destruct_handler
970230557Sjimharris      },
971230557Sjimharris      scic_sds_request_default_tc_completion_handler,
972230557Sjimharris      scic_sds_request_default_event_handler,
973230557Sjimharris      scic_sds_stp_request_non_data_await_d2h_frame_handler
974230557Sjimharris   }
975230557Sjimharris};
976230557Sjimharris
977230557Sjimharrisstatic
978230557Sjimharrisvoid scic_sds_stp_request_started_non_data_await_h2d_completion_enter(
979230557Sjimharris   SCI_BASE_OBJECT_T *object
980230557Sjimharris)
981230557Sjimharris{
982230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
983230557Sjimharris
984230557Sjimharris   SET_STATE_HANDLER(
985230557Sjimharris      this_request,
986230557Sjimharris      scic_sds_stp_request_started_non_data_substate_handler_table,
987230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
988230557Sjimharris   );
989230557Sjimharris
990230557Sjimharris   scic_sds_remote_device_set_working_request(
991230557Sjimharris      this_request->target_device, this_request
992230557Sjimharris   );
993230557Sjimharris}
994230557Sjimharris
995230557Sjimharrisstatic
996230557Sjimharrisvoid scic_sds_stp_request_started_non_data_await_d2h_enter(
997230557Sjimharris   SCI_BASE_OBJECT_T *object
998230557Sjimharris)
999230557Sjimharris{
1000230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1001230557Sjimharris
1002230557Sjimharris   SET_STATE_HANDLER(
1003230557Sjimharris      this_request,
1004230557Sjimharris      scic_sds_stp_request_started_non_data_substate_handler_table,
1005230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
1006230557Sjimharris   );
1007230557Sjimharris}
1008230557Sjimharris
1009230557Sjimharris// ---------------------------------------------------------------------------
1010230557Sjimharris
1011230557SjimharrisSCI_BASE_STATE_T scic_sds_stp_request_started_non_data_substate_table
1012230557Sjimharris[SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_MAX_SUBSTATES] =
1013230557Sjimharris{
1014230557Sjimharris   {
1015230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE,
1016230557Sjimharris      scic_sds_stp_request_started_non_data_await_h2d_completion_enter,
1017230557Sjimharris      NULL
1018230557Sjimharris   },
1019230557Sjimharris   {
1020230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE,
1021230557Sjimharris      scic_sds_stp_request_started_non_data_await_d2h_enter,
1022230557Sjimharris      NULL
1023230557Sjimharris   }
1024230557Sjimharris};
1025230557Sjimharris
1026230557Sjimharris//******************************************************************************
1027230557Sjimharris//* STP PIO STATE MACHINE
1028230557Sjimharris//******************************************************************************
1029230557Sjimharris
1030230557Sjimharris#define SCU_MAX_FRAME_BUFFER_SIZE  0x400  // 1K is the maximum SCU frame data payload
1031230557Sjimharris
1032230557Sjimharris/**
1033230557Sjimharris * This function will transmit DATA_FIS from (current sgl + offset) for input parameter length.
1034230557Sjimharris * current sgl and offset is alreay stored in the IO request
1035230557Sjimharris *
1036230557Sjimharris * @param[in] this_request
1037230557Sjimharris * @param[in] length
1038230557Sjimharris *
1039230557Sjimharris * @return SCI_STATUS
1040230557Sjimharris */
1041230557Sjimharrisstatic
1042230557SjimharrisSCI_STATUS scic_sds_stp_request_pio_data_out_trasmit_data_frame (
1043230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
1044230557Sjimharris   U32                  length
1045230557Sjimharris)
1046230557Sjimharris{
1047230557Sjimharris   SCI_STATUS status = SCI_SUCCESS;
1048230557Sjimharris   SCU_SGL_ELEMENT_T *  current_sgl;
1049230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *)this_request;
1050230557Sjimharris
1051230557Sjimharris   // Recycle the TC and reconstruct it for sending out DATA FIS containing
1052230557Sjimharris   // for the data from current_sgl+offset for the input length
1053230557Sjimharris   SCU_TASK_CONTEXT_T * task_context = scic_sds_controller_get_task_context_buffer(
1054230557Sjimharris                                          this_request->owning_controller,
1055230557Sjimharris                                          this_request->io_tag
1056230557Sjimharris                                       );
1057230557Sjimharris
1058230557Sjimharris   if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A)
1059230557Sjimharris   {
1060230557Sjimharris      current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A);
1061230557Sjimharris   }
1062230557Sjimharris   else
1063230557Sjimharris   {
1064230557Sjimharris      current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B);
1065230557Sjimharris   }
1066230557Sjimharris
1067230557Sjimharris   //update the TC
1068230557Sjimharris   task_context->command_iu_upper = current_sgl->address_upper;
1069230557Sjimharris   task_context->command_iu_lower = current_sgl->address_lower;
1070230557Sjimharris   task_context->transfer_length_bytes = length;
1071230557Sjimharris   task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
1072230557Sjimharris
1073230557Sjimharris   // send the new TC out.
1074230557Sjimharris   status = this_request->owning_controller->state_handlers->parent.continue_io_handler(
1075230557Sjimharris      &this_request->owning_controller->parent,
1076230557Sjimharris      &this_request->target_device->parent,
1077230557Sjimharris      &this_request->parent
1078230557Sjimharris   );
1079230557Sjimharris
1080230557Sjimharris   return status;
1081230557Sjimharris
1082230557Sjimharris}
1083230557Sjimharris
1084230557Sjimharris/**
1085230557Sjimharris *
1086230557Sjimharris *
1087230557Sjimharris * @param[in] this_request
1088230557Sjimharris *
1089230557Sjimharris * @return SCI_STATUS
1090230557Sjimharris */
1091230557Sjimharrisstatic
1092230557SjimharrisSCI_STATUS scic_sds_stp_request_pio_data_out_transmit_data(
1093230557Sjimharris   SCIC_SDS_REQUEST_T * this_sds_request
1094230557Sjimharris)
1095230557Sjimharris{
1096230557Sjimharris
1097230557Sjimharris   SCU_SGL_ELEMENT_T *  current_sgl;
1098230557Sjimharris   U32                  sgl_offset;
1099230557Sjimharris   U32                  remaining_bytes_in_current_sgl = 0;
1100230557Sjimharris   SCI_STATUS           status = SCI_SUCCESS;
1101230557Sjimharris
1102230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *)this_sds_request;
1103230557Sjimharris
1104230557Sjimharris   sgl_offset = this_sds_stp_request->type.pio.request_current.sgl_offset;
1105230557Sjimharris
1106230557Sjimharris   if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A)
1107230557Sjimharris   {
1108230557Sjimharris      current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A);
1109230557Sjimharris      remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->A.length - sgl_offset;
1110230557Sjimharris   }
1111230557Sjimharris   else
1112230557Sjimharris   {
1113230557Sjimharris      current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B);
1114230557Sjimharris      remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->B.length - sgl_offset;
1115230557Sjimharris   }
1116230557Sjimharris
1117230557Sjimharris
1118230557Sjimharris   if (this_sds_stp_request->type.pio.pio_transfer_bytes > 0)
1119230557Sjimharris   {
1120230557Sjimharris      if (this_sds_stp_request->type.pio.pio_transfer_bytes >= remaining_bytes_in_current_sgl )
1121230557Sjimharris      {
1122230557Sjimharris         //recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = remaining_bytes_in_current_sgl
1123230557Sjimharris         status = scic_sds_stp_request_pio_data_out_trasmit_data_frame (this_sds_request, remaining_bytes_in_current_sgl);
1124230557Sjimharris         if (status == SCI_SUCCESS)
1125230557Sjimharris         {
1126230557Sjimharris            this_sds_stp_request->type.pio.pio_transfer_bytes -= remaining_bytes_in_current_sgl;
1127230557Sjimharris            sgl_offset = 0;
1128230557Sjimharris         }
1129230557Sjimharris      }
1130230557Sjimharris      else if (this_sds_stp_request->type.pio.pio_transfer_bytes < remaining_bytes_in_current_sgl )
1131230557Sjimharris      {
1132230557Sjimharris         //recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = type.pio.pio_transfer_bytes
1133230557Sjimharris         scic_sds_stp_request_pio_data_out_trasmit_data_frame (this_sds_request, this_sds_stp_request->type.pio.pio_transfer_bytes);
1134230557Sjimharris
1135230557Sjimharris         if (status == SCI_SUCCESS)
1136230557Sjimharris         {
1137230557Sjimharris            //Sgl offset will be adjusted and saved for future
1138230557Sjimharris            sgl_offset += this_sds_stp_request->type.pio.pio_transfer_bytes;
1139230557Sjimharris            current_sgl->address_lower += this_sds_stp_request->type.pio.pio_transfer_bytes;
1140230557Sjimharris            this_sds_stp_request->type.pio.pio_transfer_bytes = 0;
1141230557Sjimharris         }
1142230557Sjimharris      }
1143230557Sjimharris   }
1144230557Sjimharris
1145230557Sjimharris   if (status == SCI_SUCCESS)
1146230557Sjimharris   {
1147230557Sjimharris      this_sds_stp_request->type.pio.request_current.sgl_offset = sgl_offset;
1148230557Sjimharris   }
1149230557Sjimharris
1150230557Sjimharris   return status;
1151230557Sjimharris}
1152230557Sjimharris
1153230557Sjimharris/**
1154230557Sjimharris * Copy the data from the buffer for the length specified to the IO reqeust
1155230557Sjimharris * SGL specified data region.
1156230557Sjimharris *
1157230557Sjimharris * @param[in] this_request The request that is used for the SGL processing.
1158230557Sjimharris * @param[in] data_buffer The buffer of data to be copied.
1159230557Sjimharris * @param[in] length  The length of the data transfer.
1160230557Sjimharris *
1161230557Sjimharris * @return SCI_STATUS
1162230557Sjimharris */
1163230557Sjimharrisstatic
1164230557SjimharrisSCI_STATUS scic_sds_stp_request_pio_data_in_copy_data_buffer(
1165230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request,
1166230557Sjimharris   U8                     * data_buffer,
1167230557Sjimharris   U32                      length
1168230557Sjimharris)
1169230557Sjimharris{
1170230557Sjimharris   SCI_STATUS          status;
1171230557Sjimharris   SCU_SGL_ELEMENT_T * current_sgl;
1172230557Sjimharris   U32                 sgl_offset;
1173230557Sjimharris   U32                 data_offset;
1174230557Sjimharris   U8                * source_address;
1175230557Sjimharris
1176230557Sjimharris   // Initial setup to get the current working SGL and the offset within the buffer
1177230557Sjimharris   current_sgl =
1178230557Sjimharris      (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) ?
1179230557Sjimharris         &(this_request->type.pio.request_current.sgl_pair->A) :
1180230557Sjimharris         &(this_request->type.pio.request_current.sgl_pair->B) ;
1181230557Sjimharris
1182230557Sjimharris   sgl_offset = this_request->type.pio.request_current.sgl_offset;
1183230557Sjimharris
1184230557Sjimharris   source_address = data_buffer;
1185230557Sjimharris   data_offset = this_request->type.pio.current_transfer_bytes;
1186230557Sjimharris   status = SCI_SUCCESS;
1187230557Sjimharris
1188230557Sjimharris   // While we are still doing Ok and there is more data to transfer
1189230557Sjimharris   while (
1190230557Sjimharris            (length > 0)
1191230557Sjimharris         && (status == SCI_SUCCESS)
1192230557Sjimharris         )
1193230557Sjimharris   {
1194230557Sjimharris      if (current_sgl->length == sgl_offset)
1195230557Sjimharris      {
1196230557Sjimharris         // This SGL has been exauhasted so we need to get the next SGL
1197230557Sjimharris         current_sgl = scic_sds_stp_request_pio_get_next_sgl(this_request);
1198230557Sjimharris
1199230557Sjimharris         if (current_sgl == NULL)
1200230557Sjimharris            status = SCI_FAILURE;
1201230557Sjimharris         else
1202230557Sjimharris            sgl_offset = 0;
1203230557Sjimharris      }
1204230557Sjimharris      else
1205230557Sjimharris      {
1206230557Sjimharris#ifdef ENABLE_OSSL_COPY_BUFFER
1207230557Sjimharris         scic_cb_io_request_copy_buffer(this_request, data_buffer, data_offset, length);
1208230557Sjimharris         length = 0;
1209230557Sjimharris#else
1210230557Sjimharris         U8 * destination_address;
1211230557Sjimharris         U32  copy_length;
1212230557Sjimharris
1213230557Sjimharris         destination_address = (U8 *)scic_cb_io_request_get_virtual_address_from_sgl(
1214230557Sjimharris            this_request,
1215230557Sjimharris            data_offset
1216230557Sjimharris         );
1217230557Sjimharris
1218230557Sjimharris         copy_length = MIN(length, current_sgl->length - sgl_offset);
1219230557Sjimharris
1220230557Sjimharris         memcpy(destination_address, source_address, copy_length);
1221230557Sjimharris
1222230557Sjimharris         length -= copy_length;
1223230557Sjimharris         sgl_offset += copy_length;
1224230557Sjimharris         data_offset += copy_length;
1225268073Sscottl         source_address += copy_length;
1226230557Sjimharris#endif
1227230557Sjimharris      }
1228230557Sjimharris   }
1229230557Sjimharris
1230230557Sjimharris   this_request->type.pio.request_current.sgl_offset = sgl_offset;
1231230557Sjimharris
1232230557Sjimharris   return status;
1233230557Sjimharris}
1234230557Sjimharris
1235230557Sjimharris/**
1236230557Sjimharris * Copy the data buffer to the io request data region.
1237230557Sjimharris *
1238230557Sjimharris * @param[in] this_request The PIO DATA IN request that is to receive the
1239230557Sjimharris *       data.
1240230557Sjimharris * @param[in] data_buffer The buffer to copy from.
1241230557Sjimharris *
1242230557Sjimharris * @return SCI_STATUS
1243230557Sjimharris */
1244230557Sjimharrisstatic
1245230557SjimharrisSCI_STATUS scic_sds_stp_request_pio_data_in_copy_data(
1246230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request,
1247230557Sjimharris   U8                     * data_buffer
1248230557Sjimharris)
1249230557Sjimharris{
1250230557Sjimharris   SCI_STATUS status;
1251230557Sjimharris
1252230557Sjimharris   // If there is less than 1K remaining in the transfer request
1253230557Sjimharris   // copy just the data for the transfer
1254230557Sjimharris   if (this_request->type.pio.pio_transfer_bytes < SCU_MAX_FRAME_BUFFER_SIZE)
1255230557Sjimharris   {
1256230557Sjimharris      status = scic_sds_stp_request_pio_data_in_copy_data_buffer(
1257230557Sjimharris         this_request,data_buffer,this_request->type.pio.pio_transfer_bytes);
1258230557Sjimharris
1259230557Sjimharris      if (status == SCI_SUCCESS)
1260230557Sjimharris      {
1261230557Sjimharris         // All data for this PIO request has now been copied, so we don't
1262230557Sjimharris         //  technically need to update current_transfer_bytes here - just
1263230557Sjimharris         //  doing it for completeness.
1264230557Sjimharris         this_request->type.pio.current_transfer_bytes += this_request->type.pio.pio_transfer_bytes;
1265230557Sjimharris         this_request->type.pio.pio_transfer_bytes = 0;
1266230557Sjimharris      }
1267230557Sjimharris   }
1268230557Sjimharris   else
1269230557Sjimharris   {
1270230557Sjimharris      // We are transfering the whole frame so copy
1271230557Sjimharris      status = scic_sds_stp_request_pio_data_in_copy_data_buffer(
1272230557Sjimharris         this_request, data_buffer, SCU_MAX_FRAME_BUFFER_SIZE);
1273230557Sjimharris
1274230557Sjimharris      if (status == SCI_SUCCESS)
1275230557Sjimharris      {
1276230557Sjimharris         this_request->type.pio.pio_transfer_bytes -= SCU_MAX_FRAME_BUFFER_SIZE;
1277230557Sjimharris         this_request->type.pio.current_transfer_bytes += SCU_MAX_FRAME_BUFFER_SIZE;
1278230557Sjimharris      }
1279230557Sjimharris   }
1280230557Sjimharris
1281230557Sjimharris   return status;
1282230557Sjimharris}
1283230557Sjimharris
1284230557Sjimharris/**
1285230557Sjimharris *
1286230557Sjimharris *
1287230557Sjimharris * @param[in] this_request
1288230557Sjimharris * @param[in] completion_code
1289230557Sjimharris *
1290230557Sjimharris * @return SCI_STATUS
1291230557Sjimharris */
1292230557Sjimharrisstatic
1293230557SjimharrisSCI_STATUS scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler(
1294230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
1295230557Sjimharris   U32                  completion_code
1296230557Sjimharris)
1297230557Sjimharris{
1298230557Sjimharris   SCI_STATUS status = SCI_SUCCESS;
1299230557Sjimharris
1300230557Sjimharris   SCIC_LOG_TRACE((
1301230557Sjimharris      sci_base_object_get_logger(this_request),
1302230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
1303230557Sjimharris      "scic_sds_stp_request_pio_data_in_await_h2d_completion_tc_completion_handler(0x%x, 0x%x) enter\n",
1304230557Sjimharris      this_request, completion_code
1305230557Sjimharris   ));
1306230557Sjimharris
1307230557Sjimharris   switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
1308230557Sjimharris   {
1309230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1310230557Sjimharris      scic_sds_request_set_status(
1311230557Sjimharris         this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1312230557Sjimharris      );
1313230557Sjimharris
1314230557Sjimharris      sci_base_state_machine_change_state(
1315230557Sjimharris         &this_request->started_substate_machine,
1316230557Sjimharris         SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1317230557Sjimharris      );
1318230557Sjimharris      break;
1319230557Sjimharris
1320230557Sjimharris   default:
1321230557Sjimharris      // All other completion status cause the IO to be complete.  If a NAK
1322230557Sjimharris      // was received, then it is up to the user to retry the request.
1323230557Sjimharris      scic_sds_request_set_status(
1324230557Sjimharris         this_request,
1325230557Sjimharris         SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1326230557Sjimharris         SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1327230557Sjimharris      );
1328230557Sjimharris
1329230557Sjimharris      sci_base_state_machine_change_state(
1330230557Sjimharris         &this_request->parent.state_machine,
1331230557Sjimharris         SCI_BASE_REQUEST_STATE_COMPLETED
1332230557Sjimharris      );
1333230557Sjimharris      break;
1334230557Sjimharris   }
1335230557Sjimharris
1336230557Sjimharris   return status;
1337230557Sjimharris}
1338230557Sjimharris
1339230557Sjimharris/**
1340230557Sjimharris *
1341230557Sjimharris *
1342230557Sjimharris * @param[in] this_request
1343230557Sjimharris * @param[in] frame_index
1344230557Sjimharris *
1345230557Sjimharris * @return SCI_STATUS
1346230557Sjimharris */
1347230557Sjimharrisstatic
1348230557SjimharrisSCI_STATUS scic_sds_stp_request_pio_await_frame_frame_handler(
1349230557Sjimharris   SCIC_SDS_REQUEST_T * request,
1350230557Sjimharris   U32                  frame_index
1351230557Sjimharris)
1352230557Sjimharris{
1353230557Sjimharris   SCI_STATUS               status;
1354230557Sjimharris   SATA_FIS_HEADER_T      * frame_header;
1355230557Sjimharris   U32                    * frame_buffer;
1356230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request;
1357230557Sjimharris   SCIC_SDS_CONTROLLER_T  * owning_controller;
1358230557Sjimharris
1359230557Sjimharris   this_request = (SCIC_SDS_STP_REQUEST_T *)request;
1360230557Sjimharris
1361230557Sjimharris   // Save off the controller, so that we do not touch the request after it
1362230557Sjimharris   //  is completed.
1363230557Sjimharris   owning_controller = this_request->parent.owning_controller;
1364230557Sjimharris
1365230557Sjimharris   SCIC_LOG_TRACE((
1366230557Sjimharris      sci_base_object_get_logger(this_request),
1367230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
1368230557Sjimharris      "scic_sds_stp_request_pio_data_in_await_frame_frame_handler(0x%x, 0x%x) enter\n",
1369230557Sjimharris      this_request, frame_index
1370230557Sjimharris   ));
1371230557Sjimharris
1372230557Sjimharris   status = scic_sds_unsolicited_frame_control_get_header(
1373230557Sjimharris      &(owning_controller->uf_control),
1374230557Sjimharris      frame_index,
1375230557Sjimharris      (void**) &frame_header
1376230557Sjimharris   );
1377230557Sjimharris
1378230557Sjimharris   if (status == SCI_SUCCESS)
1379230557Sjimharris   {
1380230557Sjimharris      switch (frame_header->fis_type)
1381230557Sjimharris      {
1382230557Sjimharris      case SATA_FIS_TYPE_PIO_SETUP:
1383230557Sjimharris         // Get from the frame buffer the PIO Setup Data
1384230557Sjimharris         scic_sds_unsolicited_frame_control_get_buffer(
1385230557Sjimharris            &(owning_controller->uf_control),
1386230557Sjimharris            frame_index,
1387230557Sjimharris            (void**) &frame_buffer
1388230557Sjimharris         );
1389230557Sjimharris
1390230557Sjimharris         // Get the data from the PIO Setup
1391230557Sjimharris         // The SCU Hardware returns first word in the frame_header and the rest
1392230557Sjimharris         // of the data is in the frame buffer so we need to back up one dword
1393230557Sjimharris         this_request->type.pio.pio_transfer_bytes =
1394230557Sjimharris            (U16)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->transfter_count;
1395230557Sjimharris         this_request->type.pio.ending_status =
1396230557Sjimharris            (U8)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->ending_status;
1397230557Sjimharris
1398230557Sjimharris         scic_sds_controller_copy_sata_response(
1399230557Sjimharris            &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer
1400230557Sjimharris         );
1401230557Sjimharris
1402230557Sjimharris         this_request->d2h_reg_fis.status =
1403230557Sjimharris            this_request->type.pio.ending_status;
1404230557Sjimharris
1405230557Sjimharris         //The next state is dependent on whether the request was PIO Data-in or Data out
1406230557Sjimharris         if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_IN)
1407230557Sjimharris         {
1408230557Sjimharris         sci_base_state_machine_change_state(
1409230557Sjimharris            &this_request->parent.started_substate_machine,
1410230557Sjimharris            SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1411230557Sjimharris            );
1412230557Sjimharris         }
1413230557Sjimharris         else if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT)
1414230557Sjimharris         {
1415230557Sjimharris            //Transmit data
1416230557Sjimharris            status = scic_sds_stp_request_pio_data_out_transmit_data ( request);
1417230557Sjimharris            if (status == SCI_SUCCESS)
1418230557Sjimharris            {
1419230557Sjimharris               sci_base_state_machine_change_state(
1420230557Sjimharris                  &this_request->parent.started_substate_machine,
1421230557Sjimharris                  SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1422230557Sjimharris               );
1423230557Sjimharris            }
1424230557Sjimharris         }
1425230557Sjimharris      break;
1426230557Sjimharris
1427230557Sjimharris      case SATA_FIS_TYPE_SETDEVBITS:
1428230557Sjimharris         sci_base_state_machine_change_state(
1429230557Sjimharris            &this_request->parent.started_substate_machine,
1430230557Sjimharris            SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1431230557Sjimharris            );
1432230557Sjimharris      break;
1433230557Sjimharris
1434230557Sjimharris      case SATA_FIS_TYPE_REGD2H:
1435230557Sjimharris         if ( (frame_header->status & ATA_STATUS_REG_BSY_BIT) == 0)
1436230557Sjimharris         {
1437230557Sjimharris            scic_sds_unsolicited_frame_control_get_buffer(
1438230557Sjimharris               &(owning_controller->uf_control),
1439230557Sjimharris               frame_index,
1440230557Sjimharris               (void**) &frame_buffer
1441230557Sjimharris            );
1442230557Sjimharris
1443230557Sjimharris            scic_sds_controller_copy_sata_response(
1444230557Sjimharris               &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer);
1445230557Sjimharris
1446230557Sjimharris            scic_sds_request_set_status(
1447230557Sjimharris               &this_request->parent,
1448230557Sjimharris               SCU_TASK_DONE_CHECK_RESPONSE,
1449230557Sjimharris               SCI_FAILURE_IO_RESPONSE_VALID
1450230557Sjimharris            );
1451230557Sjimharris
1452230557Sjimharris            sci_base_state_machine_change_state(
1453230557Sjimharris               &this_request->parent.parent.state_machine,
1454230557Sjimharris               SCI_BASE_REQUEST_STATE_COMPLETED
1455230557Sjimharris            );
1456230557Sjimharris         }
1457230557Sjimharris         else
1458230557Sjimharris         {
1459230557Sjimharris            // Now why is the drive sending a D2H Register FIS when it is still busy?
1460230557Sjimharris            // Do nothing since we are still in the right state.
1461230557Sjimharris            SCIC_LOG_INFO((
1462230557Sjimharris               sci_base_object_get_logger(this_request),
1463230557Sjimharris               SCIC_LOG_OBJECT_STP_IO_REQUEST,
1464230557Sjimharris               "SCIC PIO Request 0x%x received D2H Register FIS with BSY status 0x%x\n",
1465230557Sjimharris               this_request, frame_header->status
1466230557Sjimharris            ));
1467230557Sjimharris         }
1468230557Sjimharris         break;
1469230557Sjimharris
1470230557Sjimharris         default:
1471230557Sjimharris         break;
1472230557Sjimharris         }
1473230557Sjimharris
1474230557Sjimharris      // Frame is decoded return it to the controller
1475230557Sjimharris      scic_sds_controller_release_frame(
1476230557Sjimharris         owning_controller,
1477230557Sjimharris         frame_index
1478230557Sjimharris      );
1479230557Sjimharris   }
1480230557Sjimharris   else
1481230557Sjimharris   {
1482230557Sjimharris      SCIC_LOG_ERROR((
1483230557Sjimharris         sci_base_object_get_logger(this_request),
1484230557Sjimharris         SCIC_LOG_OBJECT_STP_IO_REQUEST,
1485230557Sjimharris         "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
1486230557Sjimharris         this_request, frame_index, status
1487230557Sjimharris      ));
1488230557Sjimharris   }
1489230557Sjimharris
1490230557Sjimharris   return status;
1491230557Sjimharris}
1492230557Sjimharris
1493230557Sjimharris/**
1494230557Sjimharris *
1495230557Sjimharris *
1496230557Sjimharris * @param[in] this_request
1497230557Sjimharris * @param[in] frame_index
1498230557Sjimharris *
1499230557Sjimharris * @return SCI_STATUS
1500230557Sjimharris */
1501230557Sjimharrisstatic
1502230557SjimharrisSCI_STATUS scic_sds_stp_request_pio_data_in_await_data_frame_handler(
1503230557Sjimharris   SCIC_SDS_REQUEST_T * request,
1504230557Sjimharris   U32                  frame_index
1505230557Sjimharris)
1506230557Sjimharris{
1507230557Sjimharris   SCI_STATUS               status;
1508230557Sjimharris   SATA_FIS_HEADER_T      * frame_header;
1509230557Sjimharris   SATA_FIS_DATA_T        * frame_buffer;
1510230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request;
1511230557Sjimharris   SCIC_SDS_CONTROLLER_T  * owning_controller;
1512230557Sjimharris
1513230557Sjimharris   this_request = (SCIC_SDS_STP_REQUEST_T *)request;
1514230557Sjimharris
1515230557Sjimharris   // Save off the controller, so that we do not touch the request after it
1516230557Sjimharris   //  is completed.
1517230557Sjimharris   owning_controller = this_request->parent.owning_controller;
1518230557Sjimharris
1519230557Sjimharris   SCIC_LOG_TRACE((
1520230557Sjimharris      sci_base_object_get_logger(this_request),
1521230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
1522230557Sjimharris      "scic_sds_stp_request_pio_data_in_await_data_frame_handler(0x%x, 0x%x) enter\n",
1523230557Sjimharris      this_request, frame_index
1524230557Sjimharris   ));
1525230557Sjimharris
1526230557Sjimharris   status = scic_sds_unsolicited_frame_control_get_header(
1527230557Sjimharris      &(owning_controller->uf_control),
1528230557Sjimharris      frame_index,
1529230557Sjimharris      (void**) &frame_header
1530230557Sjimharris   );
1531230557Sjimharris
1532230557Sjimharris   if (status == SCI_SUCCESS)
1533230557Sjimharris   {
1534230557Sjimharris      if (frame_header->fis_type == SATA_FIS_TYPE_DATA)
1535230557Sjimharris      {
1536230557Sjimharris         if (this_request->type.pio.request_current.sgl_pair == NULL)
1537230557Sjimharris         {
1538230557Sjimharris            this_request->parent.saved_rx_frame_index = frame_index;
1539230557Sjimharris            this_request->type.pio.pio_transfer_bytes = 0;
1540230557Sjimharris         }
1541230557Sjimharris         else
1542230557Sjimharris         {
1543230557Sjimharris            status = scic_sds_unsolicited_frame_control_get_buffer(
1544230557Sjimharris               &(owning_controller->uf_control),
1545230557Sjimharris               frame_index,
1546230557Sjimharris               (void**) &frame_buffer
1547230557Sjimharris            );
1548230557Sjimharris
1549230557Sjimharris            status = scic_sds_stp_request_pio_data_in_copy_data(this_request, (U8 *)frame_buffer);
1550230557Sjimharris
1551230557Sjimharris            // Frame is decoded return it to the controller
1552230557Sjimharris            scic_sds_controller_release_frame(
1553230557Sjimharris               owning_controller,
1554230557Sjimharris               frame_index
1555230557Sjimharris            );
1556230557Sjimharris         }
1557230557Sjimharris
1558230557Sjimharris         // Check for the end of the transfer, are there more bytes remaining
1559230557Sjimharris         // for this data transfer
1560230557Sjimharris         if (
1561230557Sjimharris               (status == SCI_SUCCESS)
1562230557Sjimharris            && (this_request->type.pio.pio_transfer_bytes == 0)
1563230557Sjimharris            )
1564230557Sjimharris         {
1565230557Sjimharris            if ((this_request->type.pio.ending_status & ATA_STATUS_REG_BSY_BIT) == 0)
1566230557Sjimharris            {
1567230557Sjimharris               scic_sds_request_set_status(
1568230557Sjimharris                  &this_request->parent,
1569230557Sjimharris                  SCU_TASK_DONE_CHECK_RESPONSE,
1570230557Sjimharris                  SCI_FAILURE_IO_RESPONSE_VALID
1571230557Sjimharris               );
1572230557Sjimharris
1573230557Sjimharris               sci_base_state_machine_change_state(
1574230557Sjimharris                  &this_request->parent.parent.state_machine,
1575230557Sjimharris                  SCI_BASE_REQUEST_STATE_COMPLETED
1576230557Sjimharris               );
1577230557Sjimharris            }
1578230557Sjimharris            else
1579230557Sjimharris            {
1580230557Sjimharris               sci_base_state_machine_change_state(
1581230557Sjimharris                  &this_request->parent.started_substate_machine,
1582230557Sjimharris                  SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1583230557Sjimharris               );
1584230557Sjimharris            }
1585230557Sjimharris         }
1586230557Sjimharris      }
1587230557Sjimharris      else
1588230557Sjimharris      {
1589230557Sjimharris         SCIC_LOG_ERROR((
1590230557Sjimharris            sci_base_object_get_logger(this_request),
1591230557Sjimharris            SCIC_LOG_OBJECT_STP_IO_REQUEST,
1592230557Sjimharris            "SCIC PIO Request 0x%x received frame %d with fis type 0x%02x when expecting a data fis.\n",
1593230557Sjimharris            this_request, frame_index, frame_header->fis_type
1594230557Sjimharris         ));
1595230557Sjimharris
1596230557Sjimharris         scic_sds_request_set_status(
1597230557Sjimharris            &this_request->parent,
1598230557Sjimharris            SCU_TASK_DONE_GOOD,
1599230557Sjimharris            SCI_FAILURE_IO_REQUIRES_SCSI_ABORT
1600230557Sjimharris         );
1601230557Sjimharris
1602230557Sjimharris         sci_base_state_machine_change_state(
1603230557Sjimharris            &this_request->parent.parent.state_machine,
1604230557Sjimharris            SCI_BASE_REQUEST_STATE_COMPLETED
1605230557Sjimharris         );
1606230557Sjimharris
1607230557Sjimharris         // Frame is decoded return it to the controller
1608230557Sjimharris         scic_sds_controller_release_frame(
1609230557Sjimharris            owning_controller,
1610230557Sjimharris            frame_index
1611230557Sjimharris         );
1612230557Sjimharris      }
1613230557Sjimharris   }
1614230557Sjimharris   else
1615230557Sjimharris   {
1616230557Sjimharris      SCIC_LOG_ERROR((
1617230557Sjimharris         sci_base_object_get_logger(this_request),
1618230557Sjimharris         SCIC_LOG_OBJECT_STP_IO_REQUEST,
1619230557Sjimharris         "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
1620230557Sjimharris         this_request, frame_index, status
1621230557Sjimharris      ));
1622230557Sjimharris   }
1623230557Sjimharris
1624230557Sjimharris   return status;
1625230557Sjimharris}
1626230557Sjimharris
1627230557Sjimharris
1628230557Sjimharris/**
1629230557Sjimharris *
1630230557Sjimharris *
1631230557Sjimharris * @param[in] this_request
1632230557Sjimharris * @param[in] completion_code
1633230557Sjimharris *
1634230557Sjimharris * @return SCI_STATUS
1635230557Sjimharris */
1636230557Sjimharrisstatic
1637230557SjimharrisSCI_STATUS scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler(
1638230557Sjimharris
1639230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
1640230557Sjimharris   U32                  completion_code
1641230557Sjimharris)
1642230557Sjimharris{
1643230557Sjimharris   SCI_STATUS  status                     = SCI_SUCCESS;
1644230557Sjimharris   BOOL        all_frames_transferred     = FALSE;
1645230557Sjimharris
1646230557Sjimharris   SCIC_SDS_STP_REQUEST_T *this_scic_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *) this_request;
1647230557Sjimharris
1648230557Sjimharris   SCIC_LOG_TRACE((
1649230557Sjimharris      sci_base_object_get_logger(this_request),
1650230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
1651230557Sjimharris      "scic_sds_stp_request_pio_data_in_await_h2d_completion_tc_completion_handler(0x%x, 0x%x) enter\n",
1652230557Sjimharris      this_request, completion_code
1653230557Sjimharris   ));
1654230557Sjimharris
1655230557Sjimharris   switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
1656230557Sjimharris   {
1657230557Sjimharris      case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1658230557Sjimharris         //Transmit data
1659230557Sjimharris         if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes != 0)
1660230557Sjimharris         {
1661230557Sjimharris            status = scic_sds_stp_request_pio_data_out_transmit_data ( this_request);
1662230557Sjimharris            if (status == SCI_SUCCESS)
1663230557Sjimharris            {
1664230557Sjimharris               if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0)
1665230557Sjimharris               all_frames_transferred = TRUE;
1666230557Sjimharris            }
1667230557Sjimharris         }
1668230557Sjimharris         else if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0)
1669230557Sjimharris         {
1670230557Sjimharris            //this will happen if the all data is written at the first time after the pio setup fis is recieved
1671230557Sjimharris            all_frames_transferred  = TRUE;
1672230557Sjimharris         }
1673230557Sjimharris
1674230557Sjimharris         //all data transferred.
1675230557Sjimharris         if (all_frames_transferred)
1676230557Sjimharris         {
1677230557Sjimharris            //Change the state to SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_FRAME_SUBSTATE
1678230557Sjimharris            //and wait for PIO_SETUP fis / or D2H REg fis.
1679230557Sjimharris            sci_base_state_machine_change_state(
1680230557Sjimharris               &this_request->started_substate_machine,
1681230557Sjimharris               SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1682230557Sjimharris            );
1683230557Sjimharris         }
1684230557Sjimharris         break;
1685230557Sjimharris
1686230557Sjimharris      default:
1687230557Sjimharris         // All other completion status cause the IO to be complete.  If a NAK
1688230557Sjimharris         // was received, then it is up to the user to retry the request.
1689230557Sjimharris         scic_sds_request_set_status(
1690230557Sjimharris            this_request,
1691230557Sjimharris            SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1692230557Sjimharris            SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1693230557Sjimharris         );
1694230557Sjimharris
1695230557Sjimharris         sci_base_state_machine_change_state(
1696230557Sjimharris            &this_request->parent.state_machine,
1697230557Sjimharris            SCI_BASE_REQUEST_STATE_COMPLETED
1698230557Sjimharris         );
1699230557Sjimharris         break;
1700230557Sjimharris   }
1701230557Sjimharris
1702230557Sjimharris   return status;
1703230557Sjimharris}
1704230557Sjimharris
1705230557Sjimharris/**
1706230557Sjimharris * This method will handle any link layer events while waiting for the data
1707230557Sjimharris * frame.
1708230557Sjimharris *
1709230557Sjimharris * @param[in] request This is the request which is receiving the event.
1710230557Sjimharris * @param[in] event_code This is the event code that the request on which the
1711230557Sjimharris *       request is expected to take action.
1712230557Sjimharris *
1713230557Sjimharris * @return SCI_STATUS
1714230557Sjimharris * @retval SCI_SUCCESS
1715230557Sjimharris * @retval SCI_FAILURE
1716230557Sjimharris */
1717230557Sjimharrisstatic
1718230557SjimharrisSCI_STATUS scic_sds_stp_request_pio_data_in_await_data_event_handler(
1719230557Sjimharris   SCIC_SDS_REQUEST_T * request,
1720230557Sjimharris   U32                  event_code
1721230557Sjimharris)
1722230557Sjimharris{
1723230557Sjimharris   SCI_STATUS status;
1724230557Sjimharris
1725230557Sjimharris   switch (scu_get_event_specifier(event_code))
1726230557Sjimharris   {
1727230557Sjimharris   case SCU_TASK_DONE_CRC_ERR << SCU_EVENT_SPECIFIC_CODE_SHIFT:
1728230557Sjimharris      // We are waiting for data and the SCU has R_ERR the data frame.
1729230557Sjimharris      // Go back to waiting for the D2H Register FIS
1730230557Sjimharris      sci_base_state_machine_change_state(
1731230557Sjimharris         &request->started_substate_machine,
1732230557Sjimharris         SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1733230557Sjimharris      );
1734230557Sjimharris
1735230557Sjimharris      status = SCI_SUCCESS;
1736230557Sjimharris      break;
1737230557Sjimharris
1738230557Sjimharris   default:
1739230557Sjimharris      SCIC_LOG_ERROR((
1740230557Sjimharris         sci_base_object_get_logger(request),
1741230557Sjimharris         SCIC_LOG_OBJECT_STP_IO_REQUEST,
1742230557Sjimharris         "SCIC PIO Request 0x%x received unexpected event 0x%08x\n",
1743230557Sjimharris         request, event_code
1744230557Sjimharris      ));
1745230557Sjimharris
1746230557Sjimharris      /// @todo Should we fail the PIO request when we get an unexpected event?
1747230557Sjimharris      status = SCI_FAILURE;
1748230557Sjimharris      break;
1749230557Sjimharris   }
1750230557Sjimharris
1751230557Sjimharris   return status;
1752230557Sjimharris}
1753230557Sjimharris
1754230557Sjimharris// ---------------------------------------------------------------------------
1755230557Sjimharris
1756230557SjimharrisSCIC_SDS_IO_REQUEST_STATE_HANDLER_T
1757230557Sjimharris   scic_sds_stp_request_started_pio_substate_handler_table
1758230557Sjimharris      [SCIC_SDS_STP_REQUEST_STARTED_PIO_MAX_SUBSTATES] =
1759230557Sjimharris{
1760230557Sjimharris   // SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
1761230557Sjimharris   {
1762230557Sjimharris      {
1763230557Sjimharris         scic_sds_request_default_start_handler,
1764230557Sjimharris         scic_sds_request_started_state_abort_handler,
1765230557Sjimharris         scic_sds_request_default_complete_handler,
1766230557Sjimharris         scic_sds_request_default_destruct_handler
1767230557Sjimharris      },
1768230557Sjimharris      scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler,
1769230557Sjimharris      scic_sds_request_default_event_handler,
1770230557Sjimharris      scic_sds_request_default_frame_handler
1771230557Sjimharris   },
1772230557Sjimharris   // SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1773230557Sjimharris   {
1774230557Sjimharris      {
1775230557Sjimharris         scic_sds_request_default_start_handler,
1776230557Sjimharris         //scic_sds_stp_pio_request_data_in_await_frame_abort_handler,
1777230557Sjimharris         scic_sds_request_started_state_abort_handler,
1778230557Sjimharris         scic_sds_request_default_complete_handler,
1779230557Sjimharris         scic_sds_request_default_destruct_handler
1780230557Sjimharris      },
1781230557Sjimharris      scic_sds_request_default_tc_completion_handler,
1782230557Sjimharris      scic_sds_request_default_event_handler,
1783230557Sjimharris      scic_sds_stp_request_pio_await_frame_frame_handler
1784230557Sjimharris   },
1785230557Sjimharris   // SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1786230557Sjimharris   {
1787230557Sjimharris      {
1788230557Sjimharris         scic_sds_request_default_start_handler,
1789230557Sjimharris         //scic_sds_stp_pio_request_data_in_await_data_abort_handler,
1790230557Sjimharris         scic_sds_request_started_state_abort_handler,
1791230557Sjimharris         scic_sds_request_default_complete_handler,
1792230557Sjimharris         scic_sds_request_default_destruct_handler
1793230557Sjimharris      },
1794230557Sjimharris      scic_sds_request_default_tc_completion_handler,
1795230557Sjimharris      scic_sds_stp_request_pio_data_in_await_data_event_handler,
1796230557Sjimharris      scic_sds_stp_request_pio_data_in_await_data_frame_handler
1797230557Sjimharris   },
1798230557Sjimharris   //SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1799230557Sjimharris   {
1800230557Sjimharris      {
1801230557Sjimharris         scic_sds_request_default_start_handler,
1802230557Sjimharris         scic_sds_request_started_state_abort_handler,
1803230557Sjimharris         scic_sds_request_default_complete_handler,
1804230557Sjimharris         scic_sds_request_default_destruct_handler
1805230557Sjimharris      },
1806230557Sjimharris      scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler,
1807230557Sjimharris      scic_sds_request_default_event_handler,
1808230557Sjimharris      scic_sds_request_default_frame_handler
1809230557Sjimharris   }
1810230557Sjimharris};
1811230557Sjimharris
1812230557Sjimharrisstatic
1813230557Sjimharrisvoid scic_sds_stp_request_started_pio_await_h2d_completion_enter(
1814230557Sjimharris   SCI_BASE_OBJECT_T *object
1815230557Sjimharris)
1816230557Sjimharris{
1817230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1818230557Sjimharris
1819230557Sjimharris   SET_STATE_HANDLER(
1820230557Sjimharris      this_request,
1821230557Sjimharris      scic_sds_stp_request_started_pio_substate_handler_table,
1822230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
1823230557Sjimharris   );
1824230557Sjimharris
1825230557Sjimharris   scic_sds_remote_device_set_working_request(
1826230557Sjimharris      this_request->target_device, this_request);
1827230557Sjimharris}
1828230557Sjimharris
1829230557Sjimharrisstatic
1830230557Sjimharrisvoid scic_sds_stp_request_started_pio_await_frame_enter(
1831230557Sjimharris   SCI_BASE_OBJECT_T *object
1832230557Sjimharris)
1833230557Sjimharris{
1834230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1835230557Sjimharris
1836230557Sjimharris   SET_STATE_HANDLER(
1837230557Sjimharris      this_request,
1838230557Sjimharris      scic_sds_stp_request_started_pio_substate_handler_table,
1839230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1840230557Sjimharris   );
1841230557Sjimharris}
1842230557Sjimharris
1843230557Sjimharrisstatic
1844230557Sjimharrisvoid scic_sds_stp_request_started_pio_data_in_await_data_enter(
1845230557Sjimharris   SCI_BASE_OBJECT_T *object
1846230557Sjimharris)
1847230557Sjimharris{
1848230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1849230557Sjimharris
1850230557Sjimharris   SET_STATE_HANDLER(
1851230557Sjimharris      this_request,
1852230557Sjimharris      scic_sds_stp_request_started_pio_substate_handler_table,
1853230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1854230557Sjimharris   );
1855230557Sjimharris}
1856230557Sjimharris
1857230557Sjimharrisstatic
1858230557Sjimharrisvoid scic_sds_stp_request_started_pio_data_out_transmit_data_enter(
1859230557Sjimharris   SCI_BASE_OBJECT_T *object
1860230557Sjimharris)
1861230557Sjimharris{
1862230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
1863230557Sjimharris
1864230557Sjimharris   SET_STATE_HANDLER(
1865230557Sjimharris      this_request,
1866230557Sjimharris      scic_sds_stp_request_started_pio_substate_handler_table,
1867230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1868230557Sjimharris   );
1869230557Sjimharris}
1870230557Sjimharris
1871230557Sjimharris// ---------------------------------------------------------------------------
1872230557Sjimharris
1873230557SjimharrisSCI_BASE_STATE_T
1874230557Sjimharris   scic_sds_stp_request_started_pio_substate_table
1875230557Sjimharris      [SCIC_SDS_STP_REQUEST_STARTED_PIO_MAX_SUBSTATES] =
1876230557Sjimharris{
1877230557Sjimharris   {
1878230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE,
1879230557Sjimharris      scic_sds_stp_request_started_pio_await_h2d_completion_enter,
1880230557Sjimharris      NULL
1881230557Sjimharris   },
1882230557Sjimharris   {
1883230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE,
1884230557Sjimharris      scic_sds_stp_request_started_pio_await_frame_enter,
1885230557Sjimharris      NULL
1886230557Sjimharris   },
1887230557Sjimharris   {
1888230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE,
1889230557Sjimharris      scic_sds_stp_request_started_pio_data_in_await_data_enter,
1890230557Sjimharris      NULL
1891230557Sjimharris   },
1892230557Sjimharris   {
1893230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE,
1894230557Sjimharris      scic_sds_stp_request_started_pio_data_out_transmit_data_enter,
1895230557Sjimharris      NULL
1896230557Sjimharris   }
1897230557Sjimharris};
1898230557Sjimharris
1899230557Sjimharris//******************************************************************************
1900230557Sjimharris//* UDMA REQUEST STATE MACHINE
1901230557Sjimharris//******************************************************************************
1902230557Sjimharris
1903230557Sjimharrisstatic
1904230557Sjimharrisvoid scic_sds_stp_request_udma_complete_request(
1905230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
1906230557Sjimharris   U32                  scu_status,
1907230557Sjimharris   SCI_STATUS           sci_status
1908230557Sjimharris)
1909230557Sjimharris{
1910230557Sjimharris   scic_sds_request_set_status(
1911230557Sjimharris      this_request, scu_status, sci_status
1912230557Sjimharris   );
1913230557Sjimharris
1914230557Sjimharris   sci_base_state_machine_change_state(
1915230557Sjimharris      &this_request->parent.state_machine,
1916230557Sjimharris      SCI_BASE_REQUEST_STATE_COMPLETED
1917230557Sjimharris   );
1918230557Sjimharris}
1919230557Sjimharris
1920230557Sjimharris/**
1921230557Sjimharris *
1922230557Sjimharris *
1923230557Sjimharris * @param[in] this_request
1924230557Sjimharris * @param[in] frame_index
1925230557Sjimharris *
1926230557Sjimharris * @return SCI_STATUS
1927230557Sjimharris */
1928230557Sjimharrisstatic
1929230557SjimharrisSCI_STATUS scic_sds_stp_request_udma_general_frame_handler(
1930230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
1931230557Sjimharris   U32                  frame_index
1932230557Sjimharris)
1933230557Sjimharris{
1934230557Sjimharris   SCI_STATUS          status;
1935230557Sjimharris   SATA_FIS_HEADER_T * frame_header;
1936230557Sjimharris   U32               * frame_buffer;
1937230557Sjimharris
1938230557Sjimharris   SCIC_LOG_TRACE((
1939230557Sjimharris      sci_base_object_get_logger(this_request),
1940230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
1941230557Sjimharris      "scic_sds_stp_pio_request_data_in_await_frame_frame_handler(0x%x, 0x%x) enter\n",
1942230557Sjimharris      this_request, frame_index
1943230557Sjimharris   ));
1944230557Sjimharris
1945230557Sjimharris   status = scic_sds_unsolicited_frame_control_get_header(
1946230557Sjimharris      &this_request->owning_controller->uf_control,
1947230557Sjimharris      frame_index,
1948230557Sjimharris      (void**) &frame_header
1949230557Sjimharris   );
1950230557Sjimharris
1951230557Sjimharris   if (
1952230557Sjimharris         (status == SCI_SUCCESS)
1953230557Sjimharris      && (frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
1954230557Sjimharris      )
1955230557Sjimharris   {
1956230557Sjimharris      scic_sds_unsolicited_frame_control_get_buffer(
1957230557Sjimharris         &this_request->owning_controller->uf_control,
1958230557Sjimharris         frame_index,
1959230557Sjimharris         (void**) &frame_buffer
1960230557Sjimharris      );
1961230557Sjimharris
1962230557Sjimharris      scic_sds_controller_copy_sata_response(
1963230557Sjimharris         &((SCIC_SDS_STP_REQUEST_T *)this_request)->d2h_reg_fis,
1964230557Sjimharris         (U32 *)frame_header,
1965230557Sjimharris         frame_buffer
1966230557Sjimharris      );
1967230557Sjimharris   }
1968230557Sjimharris
1969230557Sjimharris   scic_sds_controller_release_frame(
1970230557Sjimharris      this_request->owning_controller, frame_index);
1971230557Sjimharris
1972230557Sjimharris   return status;
1973230557Sjimharris}
1974230557Sjimharris
1975230557Sjimharris/**
1976230557Sjimharris * @brief This method process TC completions while in the state where
1977230557Sjimharris *        we are waiting for TC completions.
1978230557Sjimharris *
1979230557Sjimharris * @param[in] this_request
1980230557Sjimharris * @param[in] completion_code
1981230557Sjimharris *
1982230557Sjimharris * @return SCI_STATUS
1983230557Sjimharris */
1984230557Sjimharrisstatic
1985230557SjimharrisSCI_STATUS scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler(
1986230557Sjimharris   SCIC_SDS_REQUEST_T * request,
1987230557Sjimharris   U32                  completion_code
1988230557Sjimharris)
1989230557Sjimharris{
1990230557Sjimharris   SCI_STATUS               status = SCI_SUCCESS;
1991230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
1992230557Sjimharris
1993230557Sjimharris   switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
1994230557Sjimharris   {
1995230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1996230557Sjimharris      scic_sds_stp_request_udma_complete_request(
1997230557Sjimharris         &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1998230557Sjimharris      );
1999230557Sjimharris   break;
2000230557Sjimharris
2001230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS):
2002230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
2003230557Sjimharris      // We must check ther response buffer to see if the D2H Register FIS was
2004230557Sjimharris      // received before we got the TC completion.
2005230557Sjimharris      if (this_request->d2h_reg_fis.fis_type == SATA_FIS_TYPE_REGD2H)
2006230557Sjimharris      {
2007230557Sjimharris         scic_sds_remote_device_suspend(
2008230557Sjimharris            this_request->parent.target_device,
2009230557Sjimharris            SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))
2010230557Sjimharris         );
2011230557Sjimharris
2012230557Sjimharris         scic_sds_stp_request_udma_complete_request(
2013230557Sjimharris            &this_request->parent,
2014230557Sjimharris            SCU_TASK_DONE_CHECK_RESPONSE,
2015230557Sjimharris            SCI_FAILURE_IO_RESPONSE_VALID
2016230557Sjimharris         );
2017230557Sjimharris      }
2018230557Sjimharris      else
2019230557Sjimharris      {
2020230557Sjimharris         // If we have an error completion status for the TC then we can expect a
2021230557Sjimharris         // D2H register FIS from the device so we must change state to wait for it
2022230557Sjimharris         sci_base_state_machine_change_state(
2023230557Sjimharris            &this_request->parent.started_substate_machine,
2024230557Sjimharris            SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
2025230557Sjimharris         );
2026230557Sjimharris      }
2027230557Sjimharris   break;
2028230557Sjimharris
2029230557Sjimharris   /// @todo Check to see if any of these completion status need to wait for
2030230557Sjimharris   ///       the device to host register fis.
2031230557Sjimharris   /// @todo We can retry the command for SCU_TASK_DONE_CMD_LL_R_ERR - this comes only for B0
2032230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_INV_FIS_LEN):
2033230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
2034230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR):
2035230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR):
2036230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CRC_ERR):
2037230557Sjimharris      scic_sds_remote_device_suspend(
2038230557Sjimharris         this_request->parent.target_device,
2039230557Sjimharris         SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))
2040230557Sjimharris      );
2041230557Sjimharris      // Fall through to the default case
2042230557Sjimharris   default:
2043230557Sjimharris      // All other completion status cause the IO to be complete.
2044230557Sjimharris      SCIC_LOG_ERROR((
2045230557Sjimharris         sci_base_object_get_logger(&this_request->parent),
2046230557Sjimharris         SCIC_LOG_OBJECT_STP_IO_REQUEST,
2047230557Sjimharris         "SCIC IO Request 0x%x returning CONTROLLER_SPECIFIC_IO_ERR for completion code 0x%x\n",
2048230557Sjimharris         &this_request->parent, completion_code
2049230557Sjimharris      ));
2050230557Sjimharris      scic_sds_stp_request_udma_complete_request(
2051230557Sjimharris         &this_request->parent,
2052230557Sjimharris         SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
2053230557Sjimharris         SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2054230557Sjimharris      );
2055230557Sjimharris      break;
2056230557Sjimharris   }
2057230557Sjimharris
2058230557Sjimharris   return status;
2059230557Sjimharris}
2060230557Sjimharris
2061230557Sjimharrisstatic
2062230557SjimharrisSCI_STATUS scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler(
2063230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
2064230557Sjimharris   U32                  frame_index
2065230557Sjimharris)
2066230557Sjimharris{
2067230557Sjimharris   SCI_STATUS status;
2068230557Sjimharris
2069230557Sjimharris   // Use the general frame handler to copy the resposne data
2070230557Sjimharris   status = scic_sds_stp_request_udma_general_frame_handler(this_request, frame_index);
2071230557Sjimharris
2072230557Sjimharris   if (status == SCI_SUCCESS)
2073230557Sjimharris   {
2074230557Sjimharris      scic_sds_stp_request_udma_complete_request(
2075230557Sjimharris         this_request,
2076230557Sjimharris         SCU_TASK_DONE_CHECK_RESPONSE,
2077230557Sjimharris         SCI_FAILURE_IO_RESPONSE_VALID
2078230557Sjimharris      );
2079230557Sjimharris   }
2080230557Sjimharris
2081230557Sjimharris   return status;
2082230557Sjimharris}
2083230557Sjimharris
2084230557Sjimharris// ---------------------------------------------------------------------------
2085230557Sjimharris
2086230557SjimharrisSCIC_SDS_IO_REQUEST_STATE_HANDLER_T
2087230557Sjimharris   scic_sds_stp_request_started_udma_substate_handler_table
2088230557Sjimharris      [SCIC_SDS_STP_REQUEST_STARTED_UDMA_MAX_SUBSTATES] =
2089230557Sjimharris{
2090230557Sjimharris   // SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
2091230557Sjimharris   {
2092230557Sjimharris      {
2093230557Sjimharris         scic_sds_request_default_start_handler,
2094230557Sjimharris         scic_sds_request_started_state_abort_handler,
2095230557Sjimharris         scic_sds_request_default_complete_handler,
2096230557Sjimharris         scic_sds_request_default_destruct_handler
2097230557Sjimharris      },
2098230557Sjimharris      scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler,
2099230557Sjimharris      scic_sds_request_default_event_handler,
2100230557Sjimharris      scic_sds_stp_request_udma_general_frame_handler
2101230557Sjimharris   },
2102230557Sjimharris   // SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
2103230557Sjimharris   {
2104230557Sjimharris      {
2105230557Sjimharris         scic_sds_request_default_start_handler,
2106230557Sjimharris         scic_sds_request_started_state_abort_handler,
2107230557Sjimharris         scic_sds_request_default_complete_handler,
2108230557Sjimharris         scic_sds_request_default_destruct_handler
2109230557Sjimharris      },
2110230557Sjimharris      scic_sds_request_default_tc_completion_handler,
2111230557Sjimharris      scic_sds_request_default_event_handler,
2112230557Sjimharris      scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler
2113230557Sjimharris   }
2114230557Sjimharris};
2115230557Sjimharris
2116230557Sjimharris/**
2117230557Sjimharris *
2118230557Sjimharris *
2119230557Sjimharris * @param[in] object
2120230557Sjimharris */
2121230557Sjimharrisstatic
2122230557Sjimharrisvoid scic_sds_stp_request_started_udma_await_tc_completion_enter(
2123230557Sjimharris   SCI_BASE_OBJECT_T *object
2124230557Sjimharris)
2125230557Sjimharris{
2126230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2127230557Sjimharris
2128230557Sjimharris   SET_STATE_HANDLER(
2129230557Sjimharris      this_request,
2130230557Sjimharris      scic_sds_stp_request_started_udma_substate_handler_table,
2131230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
2132230557Sjimharris   );
2133230557Sjimharris}
2134230557Sjimharris
2135230557Sjimharris/**
2136230557Sjimharris * This state is entered when there is an TC completion failure.  The hardware
2137230557Sjimharris * received an unexpected condition while processing the IO request and now
2138230557Sjimharris * will UF the D2H register FIS to complete the IO.
2139230557Sjimharris *
2140230557Sjimharris * @param[in] object
2141230557Sjimharris */
2142230557Sjimharrisstatic
2143230557Sjimharrisvoid scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter(
2144230557Sjimharris   SCI_BASE_OBJECT_T *object
2145230557Sjimharris)
2146230557Sjimharris{
2147230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2148230557Sjimharris
2149230557Sjimharris   SET_STATE_HANDLER(
2150230557Sjimharris      this_request,
2151230557Sjimharris      scic_sds_stp_request_started_udma_substate_handler_table,
2152230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
2153230557Sjimharris   );
2154230557Sjimharris}
2155230557Sjimharris
2156230557Sjimharris// ---------------------------------------------------------------------------
2157230557Sjimharris
2158230557SjimharrisSCI_BASE_STATE_T
2159230557Sjimharris   scic_sds_stp_request_started_udma_substate_table
2160230557Sjimharris      [SCIC_SDS_STP_REQUEST_STARTED_UDMA_MAX_SUBSTATES] =
2161230557Sjimharris{
2162230557Sjimharris   {
2163230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE,
2164230557Sjimharris      scic_sds_stp_request_started_udma_await_tc_completion_enter,
2165230557Sjimharris      NULL
2166230557Sjimharris   },
2167230557Sjimharris   {
2168230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE,
2169230557Sjimharris      scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter,
2170230557Sjimharris      NULL
2171230557Sjimharris   }
2172230557Sjimharris};
2173230557Sjimharris
2174230557Sjimharris//******************************************************************************
2175230557Sjimharris//* STP SOFT RESET STATE MACHINE
2176230557Sjimharris//******************************************************************************
2177230557Sjimharris
2178230557Sjimharris/**
2179230557Sjimharris * This method processes a TC completion.  The expected TC completion is
2180230557Sjimharris * for the transmission of the H2D register FIS containing the SATA/STP
2181230557Sjimharris * non-data request.
2182230557Sjimharris *
2183230557Sjimharris * @param[in] this_request
2184230557Sjimharris * @param[in] completion_code
2185230557Sjimharris *
2186230557Sjimharris * @return This method always successfully processes the TC completion.
2187230557Sjimharris * @retval SCI_SUCCESS This value is always returned.
2188230557Sjimharris */
2189230557Sjimharrisstatic
2190230557SjimharrisSCI_STATUS scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler(
2191230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
2192230557Sjimharris   U32                  completion_code
2193230557Sjimharris)
2194230557Sjimharris{
2195230557Sjimharris   SCIC_LOG_TRACE((
2196230557Sjimharris      sci_base_object_get_logger(this_request),
2197230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
2198230557Sjimharris      "scic_sds_stp_request_soft_reset_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n",
2199230557Sjimharris      this_request, completion_code
2200230557Sjimharris   ));
2201230557Sjimharris
2202230557Sjimharris   switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
2203230557Sjimharris   {
2204230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
2205230557Sjimharris      scic_sds_request_set_status(
2206230557Sjimharris         this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
2207230557Sjimharris      );
2208230557Sjimharris
2209230557Sjimharris      sci_base_state_machine_change_state(
2210230557Sjimharris         &this_request->started_substate_machine,
2211230557Sjimharris         SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
2212230557Sjimharris      );
2213230557Sjimharris      break;
2214230557Sjimharris
2215230557Sjimharris   default:
2216230557Sjimharris      // All other completion status cause the IO to be complete.  If a NAK
2217230557Sjimharris      // was received, then it is up to the user to retry the request.
2218230557Sjimharris      scic_sds_request_set_status(
2219230557Sjimharris         this_request,
2220230557Sjimharris         SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
2221230557Sjimharris         SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2222230557Sjimharris      );
2223230557Sjimharris
2224230557Sjimharris      sci_base_state_machine_change_state(
2225230557Sjimharris         &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
2226230557Sjimharris      );
2227230557Sjimharris      break;
2228230557Sjimharris   }
2229230557Sjimharris
2230230557Sjimharris   return SCI_SUCCESS;
2231230557Sjimharris}
2232230557Sjimharris
2233230557Sjimharris/**
2234230557Sjimharris * This method processes a TC completion.  The expected TC completion is
2235230557Sjimharris * for the transmission of the H2D register FIS containing the SATA/STP
2236230557Sjimharris * non-data request.
2237230557Sjimharris *
2238230557Sjimharris * @param[in] this_request
2239230557Sjimharris * @param[in] completion_code
2240230557Sjimharris *
2241230557Sjimharris * @return This method always successfully processes the TC completion.
2242230557Sjimharris * @retval SCI_SUCCESS This value is always returned.
2243230557Sjimharris */
2244230557Sjimharrisstatic
2245230557SjimharrisSCI_STATUS scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler(
2246230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
2247230557Sjimharris   U32                  completion_code
2248230557Sjimharris)
2249230557Sjimharris{
2250230557Sjimharris   SCIC_LOG_TRACE((
2251230557Sjimharris      sci_base_object_get_logger(this_request),
2252230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
2253230557Sjimharris      "scic_sds_stp_request_soft_reset_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n",
2254230557Sjimharris      this_request, completion_code
2255230557Sjimharris   ));
2256230557Sjimharris
2257230557Sjimharris   switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
2258230557Sjimharris   {
2259230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
2260230557Sjimharris      scic_sds_request_set_status(
2261230557Sjimharris         this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
2262230557Sjimharris      );
2263230557Sjimharris
2264230557Sjimharris      sci_base_state_machine_change_state(
2265230557Sjimharris         &this_request->started_substate_machine,
2266230557Sjimharris         SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
2267230557Sjimharris      );
2268230557Sjimharris      break;
2269230557Sjimharris
2270230557Sjimharris   default:
2271230557Sjimharris      // All other completion status cause the IO to be complete.  If a NAK
2272230557Sjimharris      // was received, then it is up to the user to retry the request.
2273230557Sjimharris      scic_sds_request_set_status(
2274230557Sjimharris         this_request,
2275230557Sjimharris         SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
2276230557Sjimharris         SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2277230557Sjimharris      );
2278230557Sjimharris
2279230557Sjimharris      sci_base_state_machine_change_state(
2280230557Sjimharris         &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
2281230557Sjimharris      );
2282230557Sjimharris      break;
2283230557Sjimharris   }
2284230557Sjimharris
2285230557Sjimharris   return SCI_SUCCESS;
2286230557Sjimharris}
2287230557Sjimharris
2288230557Sjimharris/**
2289230557Sjimharris * This method processes frames received from the target while waiting
2290230557Sjimharris * for a device to host register FIS.  If a non-register FIS is received
2291230557Sjimharris * during this time, it is treated as a protocol violation from an
2292230557Sjimharris * IO perspective.
2293230557Sjimharris *
2294230557Sjimharris * @param[in] request This parameter specifies the request for which a
2295230557Sjimharris *            frame has been received.
2296230557Sjimharris * @param[in] frame_index This parameter specifies the index of the frame
2297230557Sjimharris *            that has been received.
2298230557Sjimharris *
2299230557Sjimharris * @return Indicate if the received frame was processed successfully.
2300230557Sjimharris */
2301230557Sjimharrisstatic
2302230557SjimharrisSCI_STATUS scic_sds_stp_request_soft_reset_await_d2h_frame_handler(
2303230557Sjimharris   SCIC_SDS_REQUEST_T * request,
2304230557Sjimharris   U32                  frame_index
2305230557Sjimharris)
2306230557Sjimharris{
2307230557Sjimharris   SCI_STATUS               status;
2308230557Sjimharris   SATA_FIS_HEADER_T      * frame_header;
2309230557Sjimharris   U32                    * frame_buffer;
2310230557Sjimharris   SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request;
2311230557Sjimharris
2312230557Sjimharris   // Save off the controller, so that we do not touch the request after it
2313230557Sjimharris   //  is completed.
2314230557Sjimharris   SCIC_SDS_CONTROLLER_T  * owning_controller = this_request->parent.owning_controller;
2315230557Sjimharris
2316230557Sjimharris   SCIC_LOG_TRACE((
2317230557Sjimharris      sci_base_object_get_logger(this_request),
2318230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
2319230557Sjimharris      "scic_sds_stp_request_soft_reset_await_d2h_frame_handler(0x%x, 0x%x) enter\n",
2320230557Sjimharris      this_request, frame_index
2321230557Sjimharris   ));
2322230557Sjimharris
2323230557Sjimharris   status = scic_sds_unsolicited_frame_control_get_header(
2324230557Sjimharris               &(owning_controller->uf_control),
2325230557Sjimharris               frame_index,
2326230557Sjimharris               (void**) &frame_header
2327230557Sjimharris            );
2328230557Sjimharris
2329230557Sjimharris   if (status == SCI_SUCCESS)
2330230557Sjimharris   {
2331230557Sjimharris      switch (frame_header->fis_type)
2332230557Sjimharris      {
2333230557Sjimharris      case SATA_FIS_TYPE_REGD2H:
2334230557Sjimharris         scic_sds_unsolicited_frame_control_get_buffer(
2335230557Sjimharris            &(owning_controller->uf_control),
2336230557Sjimharris            frame_index,
2337230557Sjimharris            (void**) &frame_buffer
2338230557Sjimharris         );
2339230557Sjimharris
2340230557Sjimharris         scic_sds_controller_copy_sata_response(
2341230557Sjimharris            &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer
2342230557Sjimharris         );
2343230557Sjimharris
2344230557Sjimharris         // The command has completed with error
2345230557Sjimharris         scic_sds_request_set_status(
2346230557Sjimharris            &this_request->parent,
2347230557Sjimharris            SCU_TASK_DONE_CHECK_RESPONSE,
2348230557Sjimharris            SCI_FAILURE_IO_RESPONSE_VALID
2349230557Sjimharris         );
2350230557Sjimharris         break;
2351230557Sjimharris
2352230557Sjimharris      default:
2353230557Sjimharris         SCIC_LOG_WARNING((
2354230557Sjimharris            sci_base_object_get_logger(this_request),
2355230557Sjimharris            SCIC_LOG_OBJECT_STP_IO_REQUEST,
2356230557Sjimharris            "IO Request:0x%x Frame Id:%d protocol violation occurred\n",
2357230557Sjimharris            this_request, frame_index
2358230557Sjimharris         ));
2359230557Sjimharris
2360230557Sjimharris         scic_sds_request_set_status(
2361230557Sjimharris            &this_request->parent,
2362230557Sjimharris            SCU_TASK_DONE_UNEXP_FIS,
2363230557Sjimharris            SCI_FAILURE_PROTOCOL_VIOLATION
2364230557Sjimharris         );
2365230557Sjimharris         break;
2366230557Sjimharris      }
2367230557Sjimharris
2368230557Sjimharris      sci_base_state_machine_change_state(
2369230557Sjimharris         &this_request->parent.parent.state_machine,
2370230557Sjimharris         SCI_BASE_REQUEST_STATE_COMPLETED
2371230557Sjimharris      );
2372230557Sjimharris
2373230557Sjimharris      // Frame has been decoded return it to the controller
2374230557Sjimharris      scic_sds_controller_release_frame(
2375230557Sjimharris         owning_controller, frame_index
2376230557Sjimharris      );
2377230557Sjimharris   }
2378230557Sjimharris   else
2379230557Sjimharris   {
2380230557Sjimharris      SCIC_LOG_ERROR((
2381230557Sjimharris         sci_base_object_get_logger(this_request),
2382230557Sjimharris         SCIC_LOG_OBJECT_STP_IO_REQUEST,
2383230557Sjimharris         "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n",
2384230557Sjimharris         this_request, frame_index, status
2385230557Sjimharris      ));
2386230557Sjimharris   }
2387230557Sjimharris
2388230557Sjimharris   return status;
2389230557Sjimharris}
2390230557Sjimharris
2391230557Sjimharris// ---------------------------------------------------------------------------
2392230557Sjimharris
2393230557SjimharrisSCIC_SDS_IO_REQUEST_STATE_HANDLER_T
2394230557Sjimharris   scic_sds_stp_request_started_soft_reset_substate_handler_table
2395230557Sjimharris      [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_MAX_SUBSTATES] =
2396230557Sjimharris{
2397230557Sjimharris   // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
2398230557Sjimharris   {
2399230557Sjimharris      {
2400230557Sjimharris         scic_sds_request_default_start_handler,
2401230557Sjimharris         scic_sds_request_started_state_abort_handler,
2402230557Sjimharris         scic_sds_request_default_complete_handler,
2403230557Sjimharris         scic_sds_request_default_destruct_handler
2404230557Sjimharris      },
2405230557Sjimharris      scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler,
2406230557Sjimharris      scic_sds_request_default_event_handler,
2407230557Sjimharris      scic_sds_request_default_frame_handler
2408230557Sjimharris   },
2409230557Sjimharris   // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
2410230557Sjimharris   {
2411230557Sjimharris      {
2412230557Sjimharris         scic_sds_request_default_start_handler,
2413230557Sjimharris         scic_sds_request_started_state_abort_handler,
2414230557Sjimharris         scic_sds_request_default_complete_handler,
2415230557Sjimharris         scic_sds_request_default_destruct_handler
2416230557Sjimharris      },
2417230557Sjimharris      scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler,
2418230557Sjimharris      scic_sds_request_default_event_handler,
2419230557Sjimharris      scic_sds_request_default_frame_handler
2420230557Sjimharris   },
2421230557Sjimharris   // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
2422230557Sjimharris   {
2423230557Sjimharris      {
2424230557Sjimharris         scic_sds_request_default_start_handler,
2425230557Sjimharris         scic_sds_request_started_state_abort_handler,
2426230557Sjimharris         scic_sds_request_default_complete_handler,
2427230557Sjimharris         scic_sds_request_default_destruct_handler
2428230557Sjimharris      },
2429230557Sjimharris      scic_sds_request_default_tc_completion_handler,
2430230557Sjimharris      scic_sds_request_default_event_handler,
2431230557Sjimharris      scic_sds_stp_request_soft_reset_await_d2h_frame_handler
2432230557Sjimharris   }
2433230557Sjimharris};
2434230557Sjimharris
2435230557Sjimharrisstatic
2436230557Sjimharrisvoid scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter(
2437230557Sjimharris   SCI_BASE_OBJECT_T *object
2438230557Sjimharris)
2439230557Sjimharris{
2440230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2441230557Sjimharris
2442230557Sjimharris   SET_STATE_HANDLER(
2443230557Sjimharris      this_request,
2444230557Sjimharris      scic_sds_stp_request_started_soft_reset_substate_handler_table,
2445230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
2446230557Sjimharris   );
2447230557Sjimharris
2448230557Sjimharris   scic_sds_remote_device_set_working_request(
2449230557Sjimharris      this_request->target_device, this_request
2450230557Sjimharris   );
2451230557Sjimharris}
2452230557Sjimharris
2453230557Sjimharrisstatic
2454230557Sjimharrisvoid scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter(
2455230557Sjimharris   SCI_BASE_OBJECT_T *object
2456230557Sjimharris)
2457230557Sjimharris{
2458230557Sjimharris   SCI_STATUS status;
2459230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2460230557Sjimharris   SATA_FIS_REG_H2D_T *h2d_fis;
2461230557Sjimharris   SCU_TASK_CONTEXT_T *task_context;
2462230557Sjimharris
2463230557Sjimharris   // Clear the SRST bit
2464230557Sjimharris   h2d_fis = scic_stp_io_request_get_h2d_reg_address(this_request);
2465230557Sjimharris   h2d_fis->control = 0;
2466230557Sjimharris
2467230557Sjimharris   // Clear the TC control bit
2468230557Sjimharris   task_context = scic_sds_controller_get_task_context_buffer(
2469230557Sjimharris                        this_request->owning_controller, this_request->io_tag);
2470230557Sjimharris   task_context->control_frame = 0;
2471230557Sjimharris
2472230557Sjimharris   status = this_request->owning_controller->state_handlers->parent.continue_io_handler(
2473230557Sjimharris      &this_request->owning_controller->parent,
2474230557Sjimharris      &this_request->target_device->parent,
2475230557Sjimharris      &this_request->parent
2476230557Sjimharris   );
2477230557Sjimharris
2478230557Sjimharris   if (status == SCI_SUCCESS)
2479230557Sjimharris   {
2480230557Sjimharris      SET_STATE_HANDLER(
2481230557Sjimharris         this_request,
2482230557Sjimharris         scic_sds_stp_request_started_soft_reset_substate_handler_table,
2483230557Sjimharris         SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
2484230557Sjimharris      );
2485230557Sjimharris   }
2486230557Sjimharris}
2487230557Sjimharris
2488230557Sjimharrisstatic
2489230557Sjimharrisvoid scic_sds_stp_request_started_soft_reset_await_d2h_response_enter(
2490230557Sjimharris   SCI_BASE_OBJECT_T *object
2491230557Sjimharris)
2492230557Sjimharris{
2493230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2494230557Sjimharris
2495230557Sjimharris   SET_STATE_HANDLER(
2496230557Sjimharris      this_request,
2497230557Sjimharris      scic_sds_stp_request_started_soft_reset_substate_handler_table,
2498230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
2499230557Sjimharris   );
2500230557Sjimharris}
2501230557Sjimharris
2502230557Sjimharris// ---------------------------------------------------------------------------
2503230557Sjimharris
2504230557SjimharrisSCI_BASE_STATE_T
2505230557Sjimharris   scic_sds_stp_request_started_soft_reset_substate_table
2506230557Sjimharris      [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_MAX_SUBSTATES] =
2507230557Sjimharris{
2508230557Sjimharris   {
2509230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE,
2510230557Sjimharris      scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter,
2511230557Sjimharris      NULL
2512230557Sjimharris   },
2513230557Sjimharris   {
2514230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE,
2515230557Sjimharris      scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter,
2516230557Sjimharris      NULL
2517230557Sjimharris   },
2518230557Sjimharris   {
2519230557Sjimharris      SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE,
2520230557Sjimharris      scic_sds_stp_request_started_soft_reset_await_d2h_response_enter,
2521230557Sjimharris      NULL
2522230557Sjimharris   }
2523230557Sjimharris};
2524230557Sjimharris
2525230557Sjimharris// ---------------------------------------------------------------------------
2526230557Sjimharris
2527230557SjimharrisSCI_STATUS scic_io_request_construct_basic_sata(
2528230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  scic_io_request
2529230557Sjimharris)
2530230557Sjimharris{
2531230557Sjimharris   SCI_STATUS           status;
2532230557Sjimharris   SCIC_SDS_REQUEST_T * request = (SCIC_SDS_REQUEST_T *)scic_io_request;
2533230557Sjimharris
2534230557Sjimharris   SCIC_LOG_TRACE((
2535230557Sjimharris      sci_base_object_get_logger(scic_io_request),
2536230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
2537230557Sjimharris      "scic_io_request_construct_basic_sata(0x%x) enter\n",
2538230557Sjimharris      scic_io_request
2539230557Sjimharris   ));
2540230557Sjimharris
2541230557Sjimharris   status = scic_sds_io_request_construct_sata(
2542230557Sjimharris               request,
2543230557Sjimharris               scic_cb_request_get_sat_protocol(request->user_request),
2544230557Sjimharris               scic_cb_io_request_get_transfer_length(request->user_request),
2545230557Sjimharris               scic_cb_io_request_get_data_direction(request->user_request),
2546230557Sjimharris               scic_cb_io_request_do_copy_rx_frames(request->user_request),
2547230557Sjimharris               TRUE
2548230557Sjimharris            );
2549230557Sjimharris
2550230557Sjimharris   return status;
2551230557Sjimharris}
2552230557Sjimharris
2553230557Sjimharris// ---------------------------------------------------------------------------
2554230557Sjimharris
2555230557SjimharrisSCI_STATUS scic_io_request_construct_advanced_sata(
2556230557Sjimharris   SCI_IO_REQUEST_HANDLE_T     scic_io_request,
2557230557Sjimharris   SCIC_IO_SATA_PARAMETERS_T * io_parameters
2558230557Sjimharris)
2559230557Sjimharris{
2560230557Sjimharris   SCI_STATUS           status;
2561230557Sjimharris   SCIC_SDS_REQUEST_T * request = (SCIC_SDS_REQUEST_T *)scic_io_request;
2562230557Sjimharris
2563230557Sjimharris   SCIC_LOG_TRACE((
2564230557Sjimharris      sci_base_object_get_logger(scic_io_request),
2565230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
2566230557Sjimharris      "scic_io_request_construct_basic_sata(0x%x) enter\n",
2567230557Sjimharris      scic_io_request
2568230557Sjimharris   ));
2569230557Sjimharris
2570230557Sjimharris   status = scic_sds_io_request_construct_sata(
2571230557Sjimharris               request,
2572230557Sjimharris               scic_cb_request_get_sat_protocol(request->user_request),
2573230557Sjimharris               scic_sds_request_get_sgl_element_pair(request, 0)->A.length,
2574230557Sjimharris               scic_cb_io_request_get_data_direction(request->user_request),
2575230557Sjimharris               scic_cb_io_request_do_copy_rx_frames(request->user_request),
2576230557Sjimharris               io_parameters->do_translate_sgl
2577230557Sjimharris            );
2578230557Sjimharris
2579230557Sjimharris   return status;
2580230557Sjimharris}
2581230557Sjimharris
2582