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/**
57230557Sjimharris * @file
58230557Sjimharris *
59230557Sjimharris * @brief This file contains the implementation for the operations on an
60230557Sjimharris *        SCIC_SDS_IO_REQUEST object.
61230557Sjimharris */
62230557Sjimharris
63230557Sjimharris#include <dev/isci/scil/intel_sat.h>
64230557Sjimharris#include <dev/isci/scil/intel_sata.h>
65230557Sjimharris#include <dev/isci/scil/intel_sas.h>
66230557Sjimharris#include <dev/isci/scil/sci_util.h>
67230557Sjimharris#include <dev/isci/scil/sci_base_request.h>
68230557Sjimharris#include <dev/isci/scil/scic_controller.h>
69230557Sjimharris#include <dev/isci/scil/scic_io_request.h>
70230557Sjimharris#include <dev/isci/scil/scic_remote_device.h>
71230557Sjimharris#include <dev/isci/scil/scic_user_callback.h>
72230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h>
73230557Sjimharris#include <dev/isci/scil/scic_sds_request.h>
74230557Sjimharris#include <dev/isci/scil/scic_sds_pci.h>
75230557Sjimharris#include <dev/isci/scil/scic_sds_stp_request.h>
76230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h>
77230557Sjimharris#include <dev/isci/scil/scic_sds_controller_registers.h>
78230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h>
79230557Sjimharris#include <dev/isci/scil/scic_sds_port.h>
80230557Sjimharris#include <dev/isci/scil/scic_task_request.h>
81230557Sjimharris#include <dev/isci/scil/scu_constants.h>
82230557Sjimharris#include <dev/isci/scil/scu_task_context.h>
83230557Sjimharris#include <dev/isci/scil/scic_sds_smp_request.h>
84230557Sjimharris#include <dev/isci/sci_environment.h>
85230557Sjimharris#include <dev/isci/scil/scic_sds_unsolicited_frame_control.h>
86230557Sjimharris#include <dev/isci/scil/sci_types.h>
87230557Sjimharris#include <dev/isci/scil/scu_completion_codes.h>
88230557Sjimharris#include <dev/isci/scil/intel_scsi.h>
89230557Sjimharris
90230557Sjimharris#if !defined(DISABLE_ATAPI)
91230557Sjimharris#include <dev/isci/scil/scic_sds_stp_packet_request.h>
92230557Sjimharris#endif
93230557Sjimharris
94230557Sjimharris/**
95230557Sjimharris* @struct SCI_SINGLE_LEVEL_LUN
96230557Sjimharris*
97230557Sjimharris* @brief this struct decribes the single level LUN structure
98230557Sjimharris*        as per the SAM 4.
99230557Sjimharris*/
100230557Sjimharristypedef struct SCI_SINGLE_LEVEL_LUN
101230557Sjimharris{
102230557Sjimharris    U8  bus_id              : 6;
103230557Sjimharris    U8  address_method      : 2;
104230557Sjimharris    U8  lun_number;
105230557Sjimharris    U8  second_level_lun[2];
106230557Sjimharris    U8  third_level_lun[2];
107230557Sjimharris    U8  forth_level_lun[2];
108230557Sjimharris
109230557Sjimharris} SCI_SINGLE_LEVEL_LUN_T;
110230557Sjimharris
111230557Sjimharris
112230557Sjimharris//****************************************************************************
113230557Sjimharris//* SCIC SDS IO REQUEST CONSTANTS
114230557Sjimharris//****************************************************************************
115230557Sjimharris
116230557Sjimharris/**
117230557Sjimharris * We have no timer requirements for IO requests right now
118230557Sjimharris */
119230557Sjimharris#define SCIC_SDS_IO_REQUEST_MINIMUM_TIMER_COUNT (0)
120230557Sjimharris#define SCIC_SDS_IO_REQUEST_MAXIMUM_TIMER_COUNT (0)
121230557Sjimharris
122230557Sjimharris//****************************************************************************
123230557Sjimharris//* SCIC SDS IO REQUEST MACROS
124230557Sjimharris//****************************************************************************
125230557Sjimharris
126230557Sjimharris/**
127230557Sjimharris * This is a helper macro to return the os handle for this request object.
128230557Sjimharris */
129230557Sjimharris#define scic_sds_request_get_user_request(request) \
130230557Sjimharris   ((request)->user_request)
131230557Sjimharris
132230557Sjimharris
133230557Sjimharris/**
134230557Sjimharris * This macro returns the sizeof memory required to store the an SSP IO
135230557Sjimharris * request.  This does not include the size of the SGL or SCU Task Context
136230557Sjimharris * memory.The sizeof(U32) are needed for DWORD alignment of the command IU
137230557Sjimharris * and response IU
138230557Sjimharris */
139230557Sjimharris#define scic_ssp_io_request_get_object_size() \
140230557Sjimharris   ( \
141230557Sjimharris       sizeof(SCI_SSP_COMMAND_IU_T) \
142230557Sjimharris     + sizeof (U32) \
143230557Sjimharris     + sizeof(SCI_SSP_RESPONSE_IU_T) \
144230557Sjimharris     + sizeof (U32) \
145230557Sjimharris   )
146230557Sjimharris
147230557Sjimharris/**
148230557Sjimharris * This macro returns the address of the ssp command buffer in the io
149230557Sjimharris * request memory
150230557Sjimharris */
151230557Sjimharris#define scic_sds_ssp_request_get_command_buffer_unaligned(memory) \
152230557Sjimharris   ((SCI_SSP_COMMAND_IU_T *)( \
153230557Sjimharris      ((char *)(memory)) + sizeof(SCIC_SDS_REQUEST_T) \
154230557Sjimharris   ))
155230557Sjimharris
156230557Sjimharris/**
157230557Sjimharris * This macro aligns the ssp command buffer in DWORD alignment
158230557Sjimharris*/
159230557Sjimharris#define scic_sds_ssp_request_align_command_buffer(address) \
160230557Sjimharris   ((SCI_SSP_COMMAND_IU_T *)( \
161230557Sjimharris      (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \
162230557Sjimharris         & ~(sizeof(U32)- 1) \
163230557Sjimharris   ))
164230557Sjimharris
165230557Sjimharris/**
166230557Sjimharris * This macro returns the DWORD-aligned ssp command buffer
167230557Sjimharris*/
168230557Sjimharris#define scic_sds_ssp_request_get_command_buffer(memory) \
169230557Sjimharris   ((SCI_SSP_COMMAND_IU_T *)  \
170230557Sjimharris      ((char *)scic_sds_ssp_request_align_command_buffer( \
171230557Sjimharris         (char *) scic_sds_ssp_request_get_command_buffer_unaligned(memory) \
172230557Sjimharris   )))
173230557Sjimharris
174230557Sjimharris/**
175230557Sjimharris * This macro returns the address of the ssp response buffer in the io
176230557Sjimharris * request memory
177230557Sjimharris */
178230557Sjimharris#define scic_sds_ssp_request_get_response_buffer_unaligned(memory) \
179230557Sjimharris   ((SCI_SSP_RESPONSE_IU_T *)( \
180230557Sjimharris         ((char *)(scic_sds_ssp_request_get_command_buffer(memory))) \
181230557Sjimharris       + sizeof(SCI_SSP_COMMAND_IU_T) \
182230557Sjimharris   ))
183230557Sjimharris
184230557Sjimharris/**
185230557Sjimharris * This macro aligns the ssp response buffer in DWORD-aligned fashion
186230557Sjimharris */
187230557Sjimharris#define scic_sds_ssp_request_align_response_buffer(memory) \
188230557Sjimharris   ((SCI_SSP_RESPONSE_IU_T *)( \
189230557Sjimharris      (((POINTER_UINT)(memory)) + (sizeof(U32) - 1)) \
190230557Sjimharris         & ~(sizeof(U32)- 1) \
191230557Sjimharris   ))
192230557Sjimharris
193230557Sjimharris/**
194230557Sjimharris * This macro returns the DWORD-aligned ssp response buffer
195230557Sjimharris*/
196230557Sjimharris#define scic_sds_ssp_request_get_response_buffer(memory) \
197230557Sjimharris   ((SCI_SSP_RESPONSE_IU_T *) \
198230557Sjimharris      ((char *)scic_sds_ssp_request_align_response_buffer ( \
199230557Sjimharris         (char *)scic_sds_ssp_request_get_response_buffer_unaligned(memory) \
200230557Sjimharris   )))
201230557Sjimharris
202230557Sjimharris/**
203230557Sjimharris * This macro returns the address of the task context buffer in the io
204230557Sjimharris * request memory
205230557Sjimharris */
206230557Sjimharris#define scic_sds_ssp_request_get_task_context_buffer_unaligned(memory) \
207230557Sjimharris   ((SCU_TASK_CONTEXT_T *)( \
208230557Sjimharris        ((char *)(scic_sds_ssp_request_get_response_buffer(memory))) \
209230557Sjimharris      + sizeof(SCI_SSP_RESPONSE_IU_T) \
210230557Sjimharris   ))
211230557Sjimharris
212230557Sjimharris/**
213230557Sjimharris * This macro returns the aligned task context buffer
214230557Sjimharris */
215230557Sjimharris#define scic_sds_ssp_request_get_task_context_buffer(memory) \
216230557Sjimharris   ((SCU_TASK_CONTEXT_T *)( \
217230557Sjimharris      ((char *)scic_sds_request_align_task_context_buffer( \
218230557Sjimharris         (char *)scic_sds_ssp_request_get_task_context_buffer_unaligned(memory)) \
219230557Sjimharris    )))
220230557Sjimharris
221230557Sjimharris/**
222230557Sjimharris * This macro returns the address of the sgl elment pairs in the io request
223230557Sjimharris * memory buffer
224230557Sjimharris */
225230557Sjimharris#define scic_sds_ssp_request_get_sgl_element_buffer(memory) \
226230557Sjimharris   ((SCU_SGL_ELEMENT_PAIR_T *)( \
227230557Sjimharris        ((char *)(scic_sds_ssp_request_get_task_context_buffer(memory))) \
228230557Sjimharris      + sizeof(SCU_TASK_CONTEXT_T) \
229230557Sjimharris    ))
230230557Sjimharris
231230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT)
232230557Sjimharris
233230557Sjimharris/**
234230557Sjimharris * This macro returns the sizeof of memory required to store an SSP Task
235230557Sjimharris * request.  This does not include the size of the SCU Task Context memory.
236230557Sjimharris */
237230557Sjimharris#define scic_ssp_task_request_get_object_size() \
238230557Sjimharris   ( \
239230557Sjimharris       sizeof(SCI_SSP_TASK_IU_T) \
240230557Sjimharris     + sizeof(SCI_SSP_RESPONSE_IU_T) \
241230557Sjimharris   )
242230557Sjimharris
243230557Sjimharris/**
244230557Sjimharris * This macro returns the address of the ssp command buffer in the task
245230557Sjimharris * request memory.  Yes its the same as the above macro except for the
246230557Sjimharris * name.
247230557Sjimharris */
248230557Sjimharris#define scic_sds_ssp_task_request_get_command_buffer(memory) \
249230557Sjimharris   ((SCI_SSP_TASK_IU_T *)( \
250230557Sjimharris        ((char *)(memory)) + sizeof(SCIC_SDS_REQUEST_T) \
251230557Sjimharris   ))
252230557Sjimharris
253230557Sjimharris/**
254230557Sjimharris * This macro returns the address of the ssp response buffer in the task
255230557Sjimharris * request memory.
256230557Sjimharris */
257230557Sjimharris#define scic_sds_ssp_task_request_get_response_buffer(memory) \
258230557Sjimharris   ((SCI_SSP_RESPONSE_IU_T *)( \
259230557Sjimharris        ((char *)(scic_sds_ssp_task_request_get_command_buffer(memory))) \
260230557Sjimharris      + sizeof(SCI_SSP_TASK_IU_T) \
261230557Sjimharris   ))
262230557Sjimharris
263230557Sjimharris/**
264230557Sjimharris * This macro returs the task context buffer for the SSP task request.
265230557Sjimharris */
266230557Sjimharris#define scic_sds_ssp_task_request_get_task_context_buffer(memory) \
267230557Sjimharris   ((SCU_TASK_CONTEXT_T *)( \
268230557Sjimharris        ((char *)(scic_sds_ssp_task_request_get_response_buffer(memory))) \
269230557Sjimharris      + sizeof(SCI_SSP_RESPONSE_IU_T) \
270230557Sjimharris   ))
271230557Sjimharris
272230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT)
273230557Sjimharris
274230557Sjimharris
275230557Sjimharris//****************************************************************************
276230557Sjimharris//* SCIC SDS IO REQUEST PRIVATE METHODS
277230557Sjimharris//****************************************************************************
278230557Sjimharris
279230557Sjimharris#ifdef SCI_LOGGING
280230557Sjimharris/**
281230557Sjimharris * This method will initialize state transition logging for the task request
282230557Sjimharris * object.
283230557Sjimharris *
284230557Sjimharris * @param[in] this_request This is the request for which to track state
285230557Sjimharris *       transitions.
286230557Sjimharris */
287230557Sjimharrisvoid scic_sds_request_initialize_state_logging(
288230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
289230557Sjimharris)
290230557Sjimharris{
291230557Sjimharris   sci_base_state_machine_logger_initialize(
292230557Sjimharris      &this_request->parent.state_machine_logger,
293230557Sjimharris      &this_request->parent.state_machine,
294230557Sjimharris      &this_request->parent.parent,
295230557Sjimharris      scic_cb_logger_log_states,
296230557Sjimharris      this_request->is_task_management_request ?
297230557Sjimharris      "SCIC_SDS_IO_REQUEST_T(Task)" : "SCIC_SDS_IO_REQUEST_T(IO)",
298230557Sjimharris      "base state machine",
299230557Sjimharris      SCIC_LOG_OBJECT_SMP_IO_REQUEST |
300230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST |
301230557Sjimharris      SCIC_LOG_OBJECT_SSP_IO_REQUEST
302230557Sjimharris   );
303230557Sjimharris
304230557Sjimharris   if (this_request->has_started_substate_machine)
305230557Sjimharris   {
306230557Sjimharris      sci_base_state_machine_logger_initialize(
307230557Sjimharris         &this_request->started_substate_machine_logger,
308230557Sjimharris         &this_request->started_substate_machine,
309230557Sjimharris         &this_request->parent.parent,
310230557Sjimharris         scic_cb_logger_log_states,
311230557Sjimharris         "SCIC_SDS_IO_REQUEST_T(Task)", "starting substate machine",
312230557Sjimharris         SCIC_LOG_OBJECT_SMP_IO_REQUEST |
313230557Sjimharris         SCIC_LOG_OBJECT_STP_IO_REQUEST |
314230557Sjimharris         SCIC_LOG_OBJECT_SSP_IO_REQUEST
315230557Sjimharris     );
316230557Sjimharris   }
317230557Sjimharris}
318230557Sjimharris
319230557Sjimharris/**
320230557Sjimharris * This method will stop the state transition logging for the task request
321230557Sjimharris * object.
322230557Sjimharris *
323230557Sjimharris * @param[in] this_request The task request object on which to stop state
324230557Sjimharris *       transition logging.
325230557Sjimharris */
326230557Sjimharrisvoid scic_sds_request_deinitialize_state_logging(
327230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
328230557Sjimharris)
329230557Sjimharris{
330230557Sjimharris   sci_base_state_machine_logger_deinitialize(
331230557Sjimharris      &this_request->parent.state_machine_logger,
332230557Sjimharris      &this_request->parent.state_machine
333230557Sjimharris   );
334230557Sjimharris
335230557Sjimharris   if (this_request->has_started_substate_machine)
336230557Sjimharris   {
337230557Sjimharris      sci_base_state_machine_logger_deinitialize(
338230557Sjimharris         &this_request->started_substate_machine_logger,
339230557Sjimharris         &this_request->started_substate_machine
340230557Sjimharris      );
341230557Sjimharris   }
342230557Sjimharris}
343230557Sjimharris#endif // SCI_LOGGING
344230557Sjimharris
345230557Sjimharris/**
346230557Sjimharris * This method returns the size required to store an SSP IO request object.
347230557Sjimharris *
348230557Sjimharris * @return U32
349230557Sjimharris */
350230557Sjimharrisstatic
351230557SjimharrisU32 scic_sds_ssp_request_get_object_size(void)
352230557Sjimharris{
353230557Sjimharris   return   sizeof(SCIC_SDS_REQUEST_T)
354230557Sjimharris          + scic_ssp_io_request_get_object_size()
355230557Sjimharris          + sizeof(SCU_TASK_CONTEXT_T)
356230557Sjimharris          + CACHE_LINE_SIZE
357230557Sjimharris          + sizeof(SCU_SGL_ELEMENT_PAIR_T) * SCU_MAX_SGL_ELEMENT_PAIRS;
358230557Sjimharris}
359230557Sjimharris
360230557Sjimharris/**
361230557Sjimharris * @brief This method returns the sgl element pair for the specificed
362230557Sjimharris *        sgl_pair index.
363230557Sjimharris *
364230557Sjimharris * @param[in] this_request This parameter specifies the IO request for which
365230557Sjimharris *            to retrieve the Scatter-Gather List element pair.
366230557Sjimharris * @param[in] sgl_pair_index This parameter specifies the index into the SGL
367230557Sjimharris *            element pair to be retrieved.
368230557Sjimharris *
369230557Sjimharris * @return This method returns a pointer to an SCU_SGL_ELEMENT_PAIR.
370230557Sjimharris */
371230557SjimharrisSCU_SGL_ELEMENT_PAIR_T *scic_sds_request_get_sgl_element_pair(
372230557Sjimharris   SCIC_SDS_REQUEST_T *this_request,
373230557Sjimharris   U32                 sgl_pair_index
374230557Sjimharris)
375230557Sjimharris{
376230557Sjimharris   SCU_TASK_CONTEXT_T *task_context;
377230557Sjimharris
378230557Sjimharris   task_context = (SCU_TASK_CONTEXT_T *)this_request->task_context_buffer;
379230557Sjimharris
380230557Sjimharris   if (sgl_pair_index == 0)
381230557Sjimharris   {
382230557Sjimharris      return &task_context->sgl_pair_ab;
383230557Sjimharris   }
384230557Sjimharris   else if (sgl_pair_index == 1)
385230557Sjimharris   {
386230557Sjimharris      return &task_context->sgl_pair_cd;
387230557Sjimharris   }
388230557Sjimharris
389230557Sjimharris   return &this_request->sgl_element_pair_buffer[sgl_pair_index - 2];
390230557Sjimharris}
391230557Sjimharris
392230557Sjimharris/**
393230557Sjimharris * @brief This function will build the SGL list for an IO request.
394230557Sjimharris *
395230557Sjimharris * @param[in] this_request This parameter specifies the IO request for which
396230557Sjimharris *            to build the Scatter-Gather List.
397230557Sjimharris *
398230557Sjimharris * @return none
399230557Sjimharris */
400230557Sjimharrisvoid scic_sds_request_build_sgl(
401230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
402230557Sjimharris)
403230557Sjimharris{
404230557Sjimharris   void                   *os_sge;
405230557Sjimharris   void                   *os_handle;
406230557Sjimharris   SCI_PHYSICAL_ADDRESS    physical_address;
407230557Sjimharris   U32                     sgl_pair_index = 0;
408230557Sjimharris   SCU_SGL_ELEMENT_PAIR_T *scu_sgl_list   = NULL;
409230557Sjimharris   SCU_SGL_ELEMENT_PAIR_T *previous_pair  = NULL;
410230557Sjimharris
411230557Sjimharris   os_handle = scic_sds_request_get_user_request(this_request);
412230557Sjimharris   scic_cb_io_request_get_next_sge(os_handle, NULL, &os_sge);
413230557Sjimharris
414230557Sjimharris   while (os_sge != NULL)
415230557Sjimharris   {
416230557Sjimharris      scu_sgl_list =
417230557Sjimharris         scic_sds_request_get_sgl_element_pair(this_request, sgl_pair_index);
418230557Sjimharris
419230557Sjimharris      SCU_SGL_COPY(os_handle, scu_sgl_list->A, os_sge);
420230557Sjimharris
421230557Sjimharris      scic_cb_io_request_get_next_sge(os_handle, os_sge, &os_sge);
422230557Sjimharris
423230557Sjimharris      if (os_sge != NULL)
424230557Sjimharris      {
425230557Sjimharris         SCU_SGL_COPY(os_handle, scu_sgl_list->B, os_sge);
426230557Sjimharris
427230557Sjimharris         scic_cb_io_request_get_next_sge(os_handle, os_sge, &os_sge);
428230557Sjimharris      }
429230557Sjimharris      else
430230557Sjimharris      {
431230557Sjimharris         SCU_SGL_ZERO(scu_sgl_list->B);
432230557Sjimharris      }
433230557Sjimharris
434230557Sjimharris      if (previous_pair != NULL)
435230557Sjimharris      {
436230557Sjimharris         scic_cb_io_request_get_physical_address(
437230557Sjimharris            scic_sds_request_get_controller(this_request),
438230557Sjimharris            this_request,
439230557Sjimharris            scu_sgl_list,
440230557Sjimharris            &physical_address
441230557Sjimharris         );
442230557Sjimharris
443230557Sjimharris         previous_pair->next_pair_upper =
444230557Sjimharris            sci_cb_physical_address_upper(physical_address);
445230557Sjimharris         previous_pair->next_pair_lower =
446230557Sjimharris            sci_cb_physical_address_lower(physical_address);
447230557Sjimharris      }
448230557Sjimharris
449230557Sjimharris      previous_pair = scu_sgl_list;
450230557Sjimharris      sgl_pair_index++;
451230557Sjimharris   }
452230557Sjimharris
453230557Sjimharris   if (scu_sgl_list != NULL)
454230557Sjimharris   {
455230557Sjimharris      scu_sgl_list->next_pair_upper = 0;
456230557Sjimharris      scu_sgl_list->next_pair_lower = 0;
457230557Sjimharris   }
458230557Sjimharris}
459230557Sjimharris
460230557Sjimharris/**
461230557Sjimharris * @brief This method initializes common portions of the io request object.
462230557Sjimharris *        This includes construction of the SCI_BASE_REQUEST_T parent.
463230557Sjimharris *
464230557Sjimharris * @param[in] the_controller This parameter specifies the controller for which
465230557Sjimharris *            the request is being constructed.
466230557Sjimharris * @param[in] the_target This parameter specifies the remote device for which
467230557Sjimharris *            the request is being constructed.
468230557Sjimharris * @param[in] io_tag This parameter specifies the IO tag to be utilized for
469230557Sjimharris *            this request.  This parameter can be set to
470230557Sjimharris *            SCI_CONTROLLER_INVALID_IO_TAG.
471230557Sjimharris * @param[in] user_io_request_object This parameter specifies the user
472230557Sjimharris *            request object for which the request is being constructed.
473230557Sjimharris * @param[in] this_request This parameter specifies the request being
474230557Sjimharris *            constructed.
475230557Sjimharris *
476230557Sjimharris * @return none
477230557Sjimharris */
478230557Sjimharrisstatic
479230557Sjimharrisvoid scic_sds_general_request_construct(
480230557Sjimharris   SCIC_SDS_CONTROLLER_T    * the_controller,
481230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T * the_target,
482230557Sjimharris   U16                        io_tag,
483230557Sjimharris   void                     * user_io_request_object,
484230557Sjimharris   SCIC_SDS_REQUEST_T       * this_request
485230557Sjimharris)
486230557Sjimharris{
487230557Sjimharris   sci_base_request_construct(
488230557Sjimharris      &this_request->parent,
489230557Sjimharris      sci_base_object_get_logger(the_controller),
490230557Sjimharris      scic_sds_request_state_table
491230557Sjimharris   );
492230557Sjimharris
493230557Sjimharris   this_request->io_tag = io_tag;
494230557Sjimharris   this_request->user_request = user_io_request_object;
495230557Sjimharris   this_request->owning_controller = the_controller;
496230557Sjimharris   this_request->target_device = the_target;
497230557Sjimharris   this_request->has_started_substate_machine = FALSE;
498230557Sjimharris   this_request->protocol = SCIC_NO_PROTOCOL;
499230557Sjimharris   this_request->sat_protocol = 0xFF;
500230557Sjimharris   this_request->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX;
501230557Sjimharris   this_request->device_sequence = scic_sds_remote_device_get_sequence(the_target);
502230557Sjimharris
503230557Sjimharris   this_request->sci_status   = SCI_SUCCESS;
504230557Sjimharris   this_request->scu_status   = 0;
505230557Sjimharris   this_request->post_context = 0xFFFFFFFF;
506230557Sjimharris
507230557Sjimharris   this_request->is_task_management_request = FALSE;
508230557Sjimharris
509230557Sjimharris   if (io_tag == SCI_CONTROLLER_INVALID_IO_TAG)
510230557Sjimharris   {
511230557Sjimharris      this_request->was_tag_assigned_by_user = FALSE;
512230557Sjimharris      this_request->task_context_buffer = NULL;
513230557Sjimharris   }
514230557Sjimharris   else
515230557Sjimharris   {
516230557Sjimharris      this_request->was_tag_assigned_by_user = TRUE;
517230557Sjimharris
518230557Sjimharris      this_request->task_context_buffer =
519230557Sjimharris         scic_sds_controller_get_task_context_buffer(
520230557Sjimharris            this_request->owning_controller, io_tag);
521230557Sjimharris   }
522230557Sjimharris}
523230557Sjimharris
524230557Sjimharris/**
525230557Sjimharris * @brief This method build the remainder of the IO request object.
526230557Sjimharris *
527230557Sjimharris * @pre The scic_sds_general_request_construct() must be called before this
528230557Sjimharris *      call is valid.
529230557Sjimharris *
530230557Sjimharris * @param[in] this_request This parameter specifies the request object being
531230557Sjimharris *            constructed.
532230557Sjimharris *
533230557Sjimharris * @return none
534230557Sjimharris */
535230557Sjimharrisvoid scic_sds_ssp_io_request_assign_buffers(
536230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
537230557Sjimharris)
538230557Sjimharris{
539230557Sjimharris   this_request->command_buffer =
540230557Sjimharris      scic_sds_ssp_request_get_command_buffer(this_request);
541230557Sjimharris   this_request->response_buffer =
542230557Sjimharris      scic_sds_ssp_request_get_response_buffer(this_request);
543230557Sjimharris   this_request->sgl_element_pair_buffer =
544230557Sjimharris      scic_sds_ssp_request_get_sgl_element_buffer(this_request);
545230557Sjimharris   this_request->sgl_element_pair_buffer =
546230557Sjimharris      scic_sds_request_align_sgl_element_buffer(this_request->sgl_element_pair_buffer);
547230557Sjimharris
548230557Sjimharris   if (this_request->was_tag_assigned_by_user == FALSE)
549230557Sjimharris   {
550230557Sjimharris      this_request->task_context_buffer =
551230557Sjimharris         scic_sds_ssp_request_get_task_context_buffer(this_request);
552230557Sjimharris   }
553230557Sjimharris}
554230557Sjimharris
555230557Sjimharris/**
556230557Sjimharris * @brief This method constructs the SSP Command IU data for this io
557230557Sjimharris *        request object.
558230557Sjimharris *
559230557Sjimharris * @param[in] this_request This parameter specifies the request object for
560230557Sjimharris *            which the SSP command information unit is being built.
561230557Sjimharris *
562230557Sjimharris * @return none
563230557Sjimharris */
564230557Sjimharrisstatic
565230557Sjimharrisvoid scic_sds_io_request_build_ssp_command_iu(
566230557Sjimharris   SCIC_SDS_REQUEST_T   *this_request
567230557Sjimharris)
568230557Sjimharris{
569230557Sjimharris   SCI_SINGLE_LEVEL_LUN_T lun;
570230557Sjimharris   SCI_SSP_COMMAND_IU_T *command_frame;
571230557Sjimharris   void                 *os_handle;
572230557Sjimharris   U32  cdb_length;
573230557Sjimharris   U32 *cdb_buffer;
574230557Sjimharris
575230557Sjimharris   command_frame =
576230557Sjimharris      (SCI_SSP_COMMAND_IU_T *)this_request->command_buffer;
577230557Sjimharris
578230557Sjimharris   os_handle = scic_sds_request_get_user_request(this_request);
579230557Sjimharris
580230557Sjimharris   ((U32 *)&lun)[0] = 0;
581230557Sjimharris   ((U32 *)&lun)[1] = 0;
582230557Sjimharris   lun.lun_number = scic_cb_ssp_io_request_get_lun(os_handle) &0xff;
583230557Sjimharris   /// @todo Is it ok to leave junk at the end of the cdb buffer?
584230557Sjimharris   scic_word_copy_with_swap(
585230557Sjimharris       (U32 *)command_frame->lun,
586230557Sjimharris       (U32 *)&lun,
587230557Sjimharris       sizeof(lun));
588230557Sjimharris
589230557Sjimharris   ((U32 *)command_frame)[2] = 0;
590230557Sjimharris
591230557Sjimharris   cdb_length = scic_cb_ssp_io_request_get_cdb_length(os_handle);
592230557Sjimharris   cdb_buffer = (U32 *)scic_cb_ssp_io_request_get_cdb_address(os_handle);
593230557Sjimharris
594230557Sjimharris   if (cdb_length > 16)
595230557Sjimharris   {
596230557Sjimharris      command_frame->additional_cdb_length = cdb_length - 16;
597230557Sjimharris   }
598230557Sjimharris
599230557Sjimharris   /// @todo Is it ok to leave junk at the end of the cdb buffer?
600230557Sjimharris   scic_word_copy_with_swap(
601230557Sjimharris      (U32 *)(&command_frame->cdb),
602230557Sjimharris      (U32 *)(cdb_buffer),
603230557Sjimharris      (cdb_length + 3) / sizeof(U32)
604230557Sjimharris   );
605230557Sjimharris
606230557Sjimharris   command_frame->enable_first_burst = 0;
607230557Sjimharris   command_frame->task_priority =
608230557Sjimharris      scic_cb_ssp_io_request_get_command_priority(os_handle);
609230557Sjimharris   command_frame->task_attribute =
610230557Sjimharris      scic_cb_ssp_io_request_get_task_attribute(os_handle);
611230557Sjimharris}
612230557Sjimharris
613230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT)
614230557Sjimharris
615230557Sjimharris/**
616230557Sjimharris * @brief This method constructs the SSP Task IU data for this io request
617230557Sjimharris *        object.
618230557Sjimharris *
619230557Sjimharris * @param[in] this_request
620230557Sjimharris *
621230557Sjimharris * @return none
622230557Sjimharris */
623230557Sjimharrisstatic
624230557Sjimharrisvoid scic_sds_task_request_build_ssp_task_iu(
625230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
626230557Sjimharris)
627230557Sjimharris{
628230557Sjimharris   SCI_SSP_TASK_IU_T *command_frame;
629230557Sjimharris   void              *os_handle;
630230557Sjimharris
631230557Sjimharris   command_frame =
632230557Sjimharris      (SCI_SSP_TASK_IU_T *)this_request->command_buffer;
633230557Sjimharris
634230557Sjimharris   os_handle = scic_sds_request_get_user_request(this_request);
635230557Sjimharris
636230557Sjimharris   command_frame->lun_upper = 0;
637230557Sjimharris   command_frame->lun_lower = scic_cb_ssp_task_request_get_lun(os_handle);
638230557Sjimharris
639230557Sjimharris   ((U32 *)command_frame)[2] = 0;
640230557Sjimharris
641230557Sjimharris   command_frame->task_function =
642230557Sjimharris      scic_cb_ssp_task_request_get_function(os_handle);
643230557Sjimharris   command_frame->task_tag =
644230557Sjimharris      scic_cb_ssp_task_request_get_io_tag_to_manage(os_handle);
645230557Sjimharris}
646230557Sjimharris
647230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT)
648230557Sjimharris
649230557Sjimharris/**
650230557Sjimharris * @brief This method is will fill in the SCU Task Context for any type of
651230557Sjimharris *        SSP request.
652230557Sjimharris *
653230557Sjimharris * @param[in] this_request
654230557Sjimharris * @param[in] task_context
655230557Sjimharris *
656230557Sjimharris * @return none
657230557Sjimharris */
658230557Sjimharrisstatic
659230557Sjimharrisvoid scu_ssp_reqeust_construct_task_context(
660230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
661230557Sjimharris   SCU_TASK_CONTEXT_T * task_context
662230557Sjimharris)
663230557Sjimharris{
664230557Sjimharris   SCI_PHYSICAL_ADDRESS      physical_address;
665230557Sjimharris   SCIC_SDS_CONTROLLER_T    *owning_controller;
666230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T *target_device;
667230557Sjimharris   SCIC_SDS_PORT_T          *target_port;
668230557Sjimharris
669230557Sjimharris   owning_controller = scic_sds_request_get_controller(this_request);
670230557Sjimharris   target_device = scic_sds_request_get_device(this_request);
671230557Sjimharris   target_port = scic_sds_request_get_port(this_request);
672230557Sjimharris
673230557Sjimharris   // Fill in the TC with the its required data
674230557Sjimharris   task_context->abort = 0;
675230557Sjimharris   task_context->priority = 0;
676230557Sjimharris   task_context->initiator_request = 1;
677230557Sjimharris   task_context->connection_rate =
678230557Sjimharris      scic_remote_device_get_connection_rate(target_device);
679230557Sjimharris   task_context->protocol_engine_index =
680230557Sjimharris      scic_sds_controller_get_protocol_engine_group(owning_controller);
681230557Sjimharris   task_context->logical_port_index =
682230557Sjimharris      scic_sds_port_get_index(target_port);
683230557Sjimharris   task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
684230557Sjimharris   task_context->valid = SCU_TASK_CONTEXT_VALID;
685230557Sjimharris   task_context->context_type = SCU_TASK_CONTEXT_TYPE;
686230557Sjimharris
687230557Sjimharris   task_context->remote_node_index =
688230557Sjimharris      scic_sds_remote_device_get_index(this_request->target_device);
689230557Sjimharris   task_context->command_code = 0;
690230557Sjimharris
691230557Sjimharris   task_context->link_layer_control = 0;
692230557Sjimharris   task_context->do_not_dma_ssp_good_response = 1;
693230557Sjimharris   task_context->strict_ordering = 0;
694230557Sjimharris   task_context->control_frame = 0;
695230557Sjimharris   task_context->timeout_enable = 0;
696230557Sjimharris   task_context->block_guard_enable = 0;
697230557Sjimharris
698230557Sjimharris   task_context->address_modifier = 0;
699230557Sjimharris
700230557Sjimharris   //task_context->type.ssp.tag = this_request->io_tag;
701230557Sjimharris   task_context->task_phase = 0x01;
702230557Sjimharris
703230557Sjimharris   if (this_request->was_tag_assigned_by_user)
704230557Sjimharris   {
705230557Sjimharris      // Build the task context now since we have already read the data
706230557Sjimharris      this_request->post_context = (
707230557Sjimharris           SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
708230557Sjimharris         | (
709230557Sjimharris                scic_sds_controller_get_protocol_engine_group(owning_controller)
710230557Sjimharris             << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
711230557Sjimharris           )
712230557Sjimharris         | (
713230557Sjimharris                 scic_sds_port_get_index(target_port)
714230557Sjimharris              << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
715230557Sjimharris           )
716230557Sjimharris         | scic_sds_io_tag_get_index(this_request->io_tag)
717230557Sjimharris      );
718230557Sjimharris   }
719230557Sjimharris   else
720230557Sjimharris   {
721230557Sjimharris      // Build the task context now since we have already read the data
722230557Sjimharris      this_request->post_context = (
723230557Sjimharris           SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
724230557Sjimharris         | (
725230557Sjimharris               scic_sds_controller_get_protocol_engine_group(owning_controller)
726230557Sjimharris            << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
727230557Sjimharris           )
728230557Sjimharris         | (
729230557Sjimharris                scic_sds_port_get_index(target_port)
730230557Sjimharris             << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
731230557Sjimharris           )
732230557Sjimharris         // This is not assigned because we have to wait until we get a TCi
733230557Sjimharris      );
734230557Sjimharris   }
735230557Sjimharris
736230557Sjimharris   // Copy the physical address for the command buffer to the SCU Task Context
737230557Sjimharris   scic_cb_io_request_get_physical_address(
738230557Sjimharris      scic_sds_request_get_controller(this_request),
739230557Sjimharris      this_request,
740230557Sjimharris      this_request->command_buffer,
741230557Sjimharris      &physical_address
742230557Sjimharris   );
743230557Sjimharris
744230557Sjimharris   task_context->command_iu_upper =
745230557Sjimharris      sci_cb_physical_address_upper(physical_address);
746230557Sjimharris   task_context->command_iu_lower =
747230557Sjimharris      sci_cb_physical_address_lower(physical_address);
748230557Sjimharris
749230557Sjimharris   // Copy the physical address for the response buffer to the SCU Task Context
750230557Sjimharris   scic_cb_io_request_get_physical_address(
751230557Sjimharris      scic_sds_request_get_controller(this_request),
752230557Sjimharris      this_request,
753230557Sjimharris      this_request->response_buffer,
754230557Sjimharris      &physical_address
755230557Sjimharris   );
756230557Sjimharris
757230557Sjimharris   task_context->response_iu_upper =
758230557Sjimharris      sci_cb_physical_address_upper(physical_address);
759230557Sjimharris   task_context->response_iu_lower =
760230557Sjimharris      sci_cb_physical_address_lower(physical_address);
761230557Sjimharris}
762230557Sjimharris
763230557Sjimharris/**
764230557Sjimharris * @brief This method is will fill in the SCU Task Context for a SSP IO
765230557Sjimharris *        request.
766230557Sjimharris *
767230557Sjimharris * @param[in] this_request
768230557Sjimharris *
769230557Sjimharris * @return none
770230557Sjimharris */
771230557Sjimharrisstatic
772230557Sjimharrisvoid scu_ssp_io_request_construct_task_context(
773230557Sjimharris   SCIC_SDS_REQUEST_T *this_request,
774230557Sjimharris   SCI_IO_REQUEST_DATA_DIRECTION data_direction,
775230557Sjimharris   U32 transfer_length_bytes
776230557Sjimharris)
777230557Sjimharris{
778230557Sjimharris   SCU_TASK_CONTEXT_T *task_context;
779230557Sjimharris
780230557Sjimharris   task_context = scic_sds_request_get_task_context(this_request);
781230557Sjimharris
782230557Sjimharris   scu_ssp_reqeust_construct_task_context(this_request, task_context);
783230557Sjimharris
784230557Sjimharris   task_context->ssp_command_iu_length = sizeof(SCI_SSP_COMMAND_IU_T) / sizeof(U32);
785230557Sjimharris   task_context->type.ssp.frame_type = SCI_SAS_COMMAND_FRAME;
786230557Sjimharris
787230557Sjimharris   switch (data_direction)
788230557Sjimharris   {
789230557Sjimharris   case SCI_IO_REQUEST_DATA_IN:
790230557Sjimharris   case SCI_IO_REQUEST_NO_DATA:
791230557Sjimharris      task_context->task_type = SCU_TASK_TYPE_IOREAD;
792230557Sjimharris      break;
793230557Sjimharris   case SCI_IO_REQUEST_DATA_OUT:
794230557Sjimharris      task_context->task_type = SCU_TASK_TYPE_IOWRITE;
795230557Sjimharris      break;
796230557Sjimharris   }
797230557Sjimharris
798230557Sjimharris   task_context->transfer_length_bytes = transfer_length_bytes;
799230557Sjimharris
800230557Sjimharris   if (task_context->transfer_length_bytes > 0)
801230557Sjimharris   {
802230557Sjimharris      scic_sds_request_build_sgl(this_request);
803230557Sjimharris   }
804230557Sjimharris}
805230557Sjimharris
806230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT)
807230557Sjimharris
808230557Sjimharris/**
809230557Sjimharris * @brief This method will fill in the remainder of the io request object
810230557Sjimharris *        for SSP Task requests.
811230557Sjimharris *
812230557Sjimharris * @param[in] this_request
813230557Sjimharris *
814230557Sjimharris * @return none
815230557Sjimharris */
816230557Sjimharrisvoid scic_sds_ssp_task_request_assign_buffers(
817230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
818230557Sjimharris)
819230557Sjimharris{
820230557Sjimharris   // Assign all of the buffer pointers
821230557Sjimharris   this_request->command_buffer =
822230557Sjimharris      scic_sds_ssp_task_request_get_command_buffer(this_request);
823230557Sjimharris   this_request->response_buffer =
824230557Sjimharris      scic_sds_ssp_task_request_get_response_buffer(this_request);
825230557Sjimharris   this_request->sgl_element_pair_buffer = NULL;
826230557Sjimharris
827230557Sjimharris   if (this_request->was_tag_assigned_by_user == FALSE)
828230557Sjimharris   {
829230557Sjimharris      this_request->task_context_buffer =
830230557Sjimharris         scic_sds_ssp_task_request_get_task_context_buffer(this_request);
831230557Sjimharris      this_request->task_context_buffer =
832230557Sjimharris         scic_sds_request_align_task_context_buffer(this_request->task_context_buffer);
833230557Sjimharris   }
834230557Sjimharris}
835230557Sjimharris
836230557Sjimharris/**
837230557Sjimharris * @brief This method will fill in the SCU Task Context for a SSP Task
838230557Sjimharris *        request.  The following important settings are utilized:
839230557Sjimharris *          -# priority == SCU_TASK_PRIORITY_HIGH.  This ensures that the
840230557Sjimharris *             task request is issued ahead of other task destined for the
841230557Sjimharris *             same Remote Node.
842230557Sjimharris *          -# task_type == SCU_TASK_TYPE_IOREAD.  This simply indicates
843230557Sjimharris *             that a normal request type (i.e. non-raw frame) is being
844230557Sjimharris *             utilized to perform task management.
845230557Sjimharris *          -# control_frame == 1.  This ensures that the proper endianess
846230557Sjimharris *             is set so that the bytes are transmitted in the right order
847230557Sjimharris *             for a task frame.
848230557Sjimharris *
849230557Sjimharris * @param[in] this_request This parameter specifies the task request object
850230557Sjimharris *            being constructed.
851230557Sjimharris *
852230557Sjimharris * @return none
853230557Sjimharris */
854230557Sjimharrisstatic
855230557Sjimharrisvoid scu_ssp_task_request_construct_task_context(
856230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
857230557Sjimharris)
858230557Sjimharris{
859230557Sjimharris   SCU_TASK_CONTEXT_T *task_context;
860230557Sjimharris
861230557Sjimharris   task_context = scic_sds_request_get_task_context(this_request);
862230557Sjimharris
863230557Sjimharris   scu_ssp_reqeust_construct_task_context(this_request, task_context);
864230557Sjimharris
865230557Sjimharris   task_context->control_frame                = 1;
866230557Sjimharris   task_context->priority                     = SCU_TASK_PRIORITY_HIGH;
867230557Sjimharris   task_context->task_type                    = SCU_TASK_TYPE_RAW_FRAME;
868230557Sjimharris   task_context->transfer_length_bytes        = 0;
869230557Sjimharris   task_context->type.ssp.frame_type          = SCI_SAS_TASK_FRAME;
870230557Sjimharris   task_context->ssp_command_iu_length = sizeof(SCI_SSP_TASK_IU_T) / sizeof(U32);
871230557Sjimharris}
872230557Sjimharris
873230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT)
874230557Sjimharris
875230557Sjimharris#if !defined(DISABLE_PASS_THROUGH)
876230557Sjimharris/**
877230557Sjimharris * @brief This method constructs the SSP Command IU data for this
878230557Sjimharris *        ssp passthrough comand request object.
879230557Sjimharris *
880230557Sjimharris * @param[in] this_request This parameter specifies the request object for
881230557Sjimharris *            which the SSP command information unit is being built.
882230557Sjimharris *
883230557Sjimharris * @return SCI_STATUS, returns invalid parameter is cdb > 16
884230557Sjimharris */
885230557Sjimharrisstatic
886230557SjimharrisSCI_STATUS scic_sds_io_request_build_ssp_command_iu_pass_through(
887230557Sjimharris   SCIC_SDS_REQUEST_T   *this_request,
888230557Sjimharris   SCIC_SSP_PASSTHRU_REQUEST_CALLBACKS_T *ssp_passthru_cb
889230557Sjimharris)
890230557Sjimharris{
891230557Sjimharris   SCI_SSP_COMMAND_IU_T *command_frame;
892230557Sjimharris   U32  cdb_length = 0, additional_cdb_length = 0;
893230557Sjimharris   U8 *cdb_buffer, *additional_cdb_buffer;
894230557Sjimharris   U8 *scsi_lun;
895230557Sjimharris   SCI_STATUS sci_status = SCI_SUCCESS;
896230557Sjimharris   SCI_SINGLE_LEVEL_LUN_T lun;
897230557Sjimharris
898230557Sjimharris   command_frame =
899230557Sjimharris      (SCI_SSP_COMMAND_IU_T *)this_request->command_buffer;
900230557Sjimharris
901230557Sjimharris   //get the lun
902230557Sjimharris   ssp_passthru_cb->scic_cb_ssp_passthru_get_lun (
903230557Sjimharris      this_request,
904230557Sjimharris     &scsi_lun
905230557Sjimharris   );
906230557Sjimharris   memset(&lun, 0, sizeof(lun));
907230557Sjimharris   lun.lun_number = *scsi_lun;
908230557Sjimharris   scic_word_copy_with_swap(
909230557Sjimharris       (U32 *)command_frame->lun,
910230557Sjimharris       (U32 *)&lun,
911230557Sjimharris       sizeof(lun));
912230557Sjimharris
913230557Sjimharris   ((U32 *)command_frame)[2] = 0;
914230557Sjimharris
915230557Sjimharris   ssp_passthru_cb->scic_cb_ssp_passthru_get_cdb(
916230557Sjimharris      this_request,
917230557Sjimharris     &cdb_length,
918230557Sjimharris     &cdb_buffer,
919230557Sjimharris     &additional_cdb_length,
920230557Sjimharris     &additional_cdb_buffer
921230557Sjimharris   );
922230557Sjimharris
923230557Sjimharris   command_frame->additional_cdb_length = additional_cdb_length;
924230557Sjimharris
925230557Sjimharris   // ----------- TODO
926230557Sjimharris   ///todo: what to do with additional cdb length and buffer as the current command buffer is
927230557Sjimharris   // 16 bytes in intel_sas.h
928230557Sjimharris   // ??? see the SAS command IU
929230557Sjimharris   if (additional_cdb_length > 0)
930230557Sjimharris   {
931230557Sjimharris     return SCI_FAILURE_INVALID_PARAMETER_VALUE;
932230557Sjimharris   }
933230557Sjimharris
934230557Sjimharris   /// @todo Is it ok to leave junk at the end of the cdb buffer?
935230557Sjimharris   scic_word_copy_with_swap(
936230557Sjimharris      (U32 *)(&command_frame->cdb),
937230557Sjimharris      (U32 *)(cdb_buffer),
938230557Sjimharris      (cdb_length + 3) / sizeof(U32)
939230557Sjimharris   );
940230557Sjimharris
941230557Sjimharris   /////-------- End fo TODO
942230557Sjimharris
943230557Sjimharris   command_frame->enable_first_burst = 0;
944230557Sjimharris   command_frame->task_priority = 0;  //todo: check with Richard ????
945230557Sjimharris
946230557Sjimharris   //get the task attribute
947230557Sjimharris   command_frame->task_attribute = ssp_passthru_cb->scic_cb_ssp_passthru_get_task_attribute (
948230557Sjimharris                                      this_request
949230557Sjimharris                             );
950230557Sjimharris
951230557Sjimharris   return sci_status;
952230557Sjimharris}
953230557Sjimharris#endif // !defined(DISABLE_PASS_THROUGH)
954230557Sjimharris
955230557Sjimharris//****************************************************************************
956230557Sjimharris//* SCIC Interface Implementation
957230557Sjimharris//****************************************************************************
958230557Sjimharris
959230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT)
960230557Sjimharris/**
961230557Sjimharris * This method returns the size required to store an SSP task request object.
962230557Sjimharris *
963230557Sjimharris * @return U32
964230557Sjimharris */
965230557Sjimharrisstatic
966230557SjimharrisU32 scic_sds_ssp_task_request_get_object_size(void)
967230557Sjimharris{
968230557Sjimharris   return   sizeof(SCIC_SDS_REQUEST_T)
969230557Sjimharris          + scic_ssp_task_request_get_object_size()
970230557Sjimharris          + sizeof(SCU_TASK_CONTEXT_T)
971230557Sjimharris          + CACHE_LINE_SIZE;
972230557Sjimharris}
973230557Sjimharris
974230557Sjimharris
975230557SjimharrisU32 scic_task_request_get_object_size(void)
976230557Sjimharris{
977230557Sjimharris   U32 ssp_task_request_size;
978230557Sjimharris   U32 stp_task_request_size;
979230557Sjimharris
980230557Sjimharris   ssp_task_request_size = scic_sds_ssp_task_request_get_object_size();
981230557Sjimharris   stp_task_request_size = scic_sds_stp_task_request_get_object_size();
982230557Sjimharris
983230557Sjimharris   return MAX(ssp_task_request_size, stp_task_request_size);
984230557Sjimharris}
985230557Sjimharris
986230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT)
987230557Sjimharris
988230557Sjimharris// ---------------------------------------------------------------------------
989230557Sjimharris
990230557SjimharrisU32 scic_io_request_get_object_size(void)
991230557Sjimharris{
992230557Sjimharris   U32 ssp_request_size;
993230557Sjimharris   U32 stp_request_size;
994230557Sjimharris   U32 smp_request_size;
995230557Sjimharris
996230557Sjimharris   ssp_request_size = scic_sds_ssp_request_get_object_size();
997230557Sjimharris   stp_request_size = scic_sds_stp_request_get_object_size();
998230557Sjimharris   smp_request_size = scic_sds_smp_request_get_object_size();
999230557Sjimharris
1000230557Sjimharris   return MAX(ssp_request_size, MAX(stp_request_size, smp_request_size));
1001230557Sjimharris}
1002230557Sjimharris
1003230557Sjimharris// ---------------------------------------------------------------------------
1004230557Sjimharris
1005230557SjimharrisSCIC_TRANSPORT_PROTOCOL scic_io_request_get_protocol(
1006230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  scic_io_request
1007230557Sjimharris)
1008230557Sjimharris{
1009230557Sjimharris   SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T * )scic_io_request;
1010230557Sjimharris   return this_request->protocol;
1011230557Sjimharris}
1012230557Sjimharris
1013230557Sjimharris// ---------------------------------------------------------------------------
1014230557Sjimharris
1015230557SjimharrisU32 scic_sds_request_get_min_timer_count(void)
1016230557Sjimharris{
1017230557Sjimharris   return SCIC_SDS_IO_REQUEST_MINIMUM_TIMER_COUNT;
1018230557Sjimharris}
1019230557Sjimharris
1020230557Sjimharris// ---------------------------------------------------------------------------
1021230557Sjimharris
1022230557SjimharrisU32 scic_sds_request_get_max_timer_count(void)
1023230557Sjimharris{
1024230557Sjimharris   return SCIC_SDS_IO_REQUEST_MAXIMUM_TIMER_COUNT;
1025230557Sjimharris}
1026230557Sjimharris
1027230557Sjimharris// ---------------------------------------------------------------------------
1028230557Sjimharris
1029230557SjimharrisSCI_STATUS scic_io_request_construct(
1030230557Sjimharris   SCI_CONTROLLER_HANDLE_T      scic_controller,
1031230557Sjimharris   SCI_REMOTE_DEVICE_HANDLE_T   scic_remote_device,
1032230557Sjimharris   U16                          io_tag,
1033230557Sjimharris   void                       * user_io_request_object,
1034230557Sjimharris   void                       * scic_io_request_memory,
1035230557Sjimharris   SCI_IO_REQUEST_HANDLE_T    * new_scic_io_request_handle
1036230557Sjimharris)
1037230557Sjimharris{
1038230557Sjimharris   SCI_STATUS                          status = SCI_SUCCESS;
1039230557Sjimharris   SCIC_SDS_REQUEST_T                * this_request;
1040230557Sjimharris   SMP_DISCOVER_RESPONSE_PROTOCOLS_T   device_protocol;
1041230557Sjimharris
1042230557Sjimharris   this_request = (SCIC_SDS_REQUEST_T * )scic_io_request_memory;
1043230557Sjimharris
1044230557Sjimharris   SCIC_LOG_TRACE((
1045230557Sjimharris      sci_base_object_get_logger(scic_controller),
1046230557Sjimharris      (SCIC_LOG_OBJECT_SSP_IO_REQUEST
1047230557Sjimharris      |SCIC_LOG_OBJECT_SMP_IO_REQUEST
1048230557Sjimharris      |SCIC_LOG_OBJECT_STP_IO_REQUEST),
1049230557Sjimharris      "scic_io_request_construct(0x%x, 0x%x, 0x02x, 0x%x, 0x%x, 0x%x) enter\n",
1050230557Sjimharris      scic_controller, scic_remote_device,
1051230557Sjimharris      io_tag, user_io_request_object,
1052230557Sjimharris      this_request, new_scic_io_request_handle
1053230557Sjimharris   ));
1054230557Sjimharris
1055230557Sjimharris   // Build the common part of the request
1056230557Sjimharris   scic_sds_general_request_construct(
1057230557Sjimharris      (SCIC_SDS_CONTROLLER_T *)scic_controller,
1058230557Sjimharris      (SCIC_SDS_REMOTE_DEVICE_T *)scic_remote_device,
1059230557Sjimharris      io_tag,
1060230557Sjimharris      user_io_request_object,
1061230557Sjimharris      this_request
1062230557Sjimharris   );
1063230557Sjimharris
1064230557Sjimharris   if (
1065230557Sjimharris         scic_sds_remote_device_get_index((SCIC_SDS_REMOTE_DEVICE_T *)scic_remote_device)
1066230557Sjimharris      == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
1067230557Sjimharris      )
1068230557Sjimharris   {
1069230557Sjimharris      return SCI_FAILURE_INVALID_REMOTE_DEVICE;
1070230557Sjimharris   }
1071230557Sjimharris
1072230557Sjimharris   scic_remote_device_get_protocols(scic_remote_device, &device_protocol);
1073230557Sjimharris
1074230557Sjimharris   if (device_protocol.u.bits.attached_ssp_target)
1075230557Sjimharris   {
1076230557Sjimharris      scic_sds_ssp_io_request_assign_buffers(this_request);
1077230557Sjimharris   }
1078230557Sjimharris   else if (device_protocol.u.bits.attached_stp_target)
1079230557Sjimharris   {
1080230557Sjimharris      scic_sds_stp_request_assign_buffers(this_request);
1081230557Sjimharris      memset(this_request->command_buffer, 0, sizeof(SATA_FIS_REG_H2D_T));
1082230557Sjimharris   }
1083230557Sjimharris   else if (device_protocol.u.bits.attached_smp_target)
1084230557Sjimharris   {
1085230557Sjimharris      scic_sds_smp_request_assign_buffers(this_request);
1086230557Sjimharris      memset(this_request->command_buffer, 0, sizeof(SMP_REQUEST_T));
1087230557Sjimharris   }
1088230557Sjimharris   else
1089230557Sjimharris   {
1090230557Sjimharris      status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
1091230557Sjimharris   }
1092230557Sjimharris
1093230557Sjimharris   if (status == SCI_SUCCESS)
1094230557Sjimharris   {
1095230557Sjimharris      memset(
1096230557Sjimharris         this_request->task_context_buffer,
1097230557Sjimharris         0,
1098230557Sjimharris         SCI_FIELD_OFFSET(SCU_TASK_CONTEXT_T, sgl_pair_ab)
1099230557Sjimharris      );
1100230557Sjimharris      *new_scic_io_request_handle = scic_io_request_memory;
1101230557Sjimharris   }
1102230557Sjimharris
1103230557Sjimharris   return status;
1104230557Sjimharris}
1105230557Sjimharris
1106230557Sjimharris// ---------------------------------------------------------------------------
1107230557Sjimharris
1108230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT)
1109230557Sjimharris
1110230557SjimharrisSCI_STATUS scic_task_request_construct(
1111230557Sjimharris   SCI_CONTROLLER_HANDLE_T     controller,
1112230557Sjimharris   SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
1113230557Sjimharris   U16                         io_tag,
1114230557Sjimharris   void                       *user_io_request_object,
1115230557Sjimharris   void                       *scic_task_request_memory,
1116230557Sjimharris   SCI_TASK_REQUEST_HANDLE_T  *new_scic_task_request_handle
1117230557Sjimharris)
1118230557Sjimharris{
1119230557Sjimharris   SCI_STATUS           status = SCI_SUCCESS;
1120230557Sjimharris   SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)
1121230557Sjimharris                                       scic_task_request_memory;
1122230557Sjimharris   SMP_DISCOVER_RESPONSE_PROTOCOLS_T   device_protocol;
1123230557Sjimharris
1124230557Sjimharris   SCIC_LOG_TRACE((
1125230557Sjimharris      sci_base_object_get_logger(controller),
1126230557Sjimharris      (SCIC_LOG_OBJECT_SSP_IO_REQUEST
1127230557Sjimharris      |SCIC_LOG_OBJECT_SMP_IO_REQUEST
1128230557Sjimharris      |SCIC_LOG_OBJECT_STP_IO_REQUEST),
1129230557Sjimharris      "scic_task_request_construct(0x%x, 0x%x, 0x02x, 0x%x, 0x%x, 0x%x) enter\n",
1130230557Sjimharris      controller, remote_device,
1131230557Sjimharris      io_tag, user_io_request_object,
1132230557Sjimharris      scic_task_request_memory, new_scic_task_request_handle
1133230557Sjimharris   ));
1134230557Sjimharris
1135230557Sjimharris   // Build the common part of the request
1136230557Sjimharris   scic_sds_general_request_construct(
1137230557Sjimharris      (SCIC_SDS_CONTROLLER_T *)controller,
1138230557Sjimharris      (SCIC_SDS_REMOTE_DEVICE_T *)remote_device,
1139230557Sjimharris      io_tag,
1140230557Sjimharris      user_io_request_object,
1141230557Sjimharris      this_request
1142230557Sjimharris   );
1143230557Sjimharris
1144230557Sjimharris   scic_remote_device_get_protocols(remote_device, &device_protocol);
1145230557Sjimharris
1146230557Sjimharris   if (device_protocol.u.bits.attached_ssp_target)
1147230557Sjimharris   {
1148230557Sjimharris      scic_sds_ssp_task_request_assign_buffers(this_request);
1149230557Sjimharris
1150230557Sjimharris      this_request->has_started_substate_machine = TRUE;
1151230557Sjimharris
1152230557Sjimharris      // Construct the started sub-state machine.
1153230557Sjimharris      sci_base_state_machine_construct(
1154230557Sjimharris         &this_request->started_substate_machine,
1155230557Sjimharris         &this_request->parent.parent,
1156230557Sjimharris         scic_sds_io_request_started_task_mgmt_substate_table,
1157230557Sjimharris         SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION
1158230557Sjimharris      );
1159230557Sjimharris   }
1160230557Sjimharris   else if (device_protocol.u.bits.attached_stp_target)
1161230557Sjimharris   {
1162230557Sjimharris      scic_sds_stp_request_assign_buffers(this_request);
1163230557Sjimharris   }
1164230557Sjimharris   else
1165230557Sjimharris   {
1166230557Sjimharris      status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
1167230557Sjimharris   }
1168230557Sjimharris
1169230557Sjimharris   if (status == SCI_SUCCESS)
1170230557Sjimharris   {
1171230557Sjimharris      this_request->is_task_management_request = TRUE;
1172230557Sjimharris      memset(this_request->task_context_buffer, 0x00, sizeof(SCU_TASK_CONTEXT_T));
1173230557Sjimharris      *new_scic_task_request_handle            = scic_task_request_memory;
1174230557Sjimharris   }
1175230557Sjimharris
1176230557Sjimharris   return status;
1177230557Sjimharris}
1178230557Sjimharris
1179230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT)
1180230557Sjimharris
1181230557Sjimharris// ---------------------------------------------------------------------------
1182230557Sjimharris
1183230557SjimharrisSCI_STATUS scic_io_request_construct_basic_ssp(
1184230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  scic_io_request
1185230557Sjimharris)
1186230557Sjimharris{
1187230557Sjimharris   void               *os_handle;
1188230557Sjimharris   SCIC_SDS_REQUEST_T *this_request;
1189230557Sjimharris   this_request = (SCIC_SDS_REQUEST_T *)scic_io_request;
1190230557Sjimharris
1191230557Sjimharris   SCIC_LOG_TRACE((
1192230557Sjimharris      sci_base_object_get_logger(this_request),
1193230557Sjimharris      SCIC_LOG_OBJECT_SSP_IO_REQUEST,
1194230557Sjimharris      "scic_io_request_construct_basic_ssp(0x%x) enter\n",
1195230557Sjimharris      this_request
1196230557Sjimharris   ));
1197230557Sjimharris
1198230557Sjimharris   this_request->protocol = SCIC_SSP_PROTOCOL;
1199230557Sjimharris
1200230557Sjimharris   os_handle = scic_sds_request_get_user_request(this_request);
1201230557Sjimharris
1202230557Sjimharris   scu_ssp_io_request_construct_task_context(
1203230557Sjimharris      this_request,
1204230557Sjimharris      scic_cb_io_request_get_data_direction(os_handle),
1205230557Sjimharris      scic_cb_io_request_get_transfer_length(os_handle)
1206230557Sjimharris   );
1207230557Sjimharris
1208230557Sjimharris
1209230557Sjimharris   scic_sds_io_request_build_ssp_command_iu(this_request);
1210230557Sjimharris
1211230557Sjimharris   scic_sds_request_initialize_state_logging(this_request);
1212230557Sjimharris
1213230557Sjimharris   sci_base_state_machine_change_state(
1214230557Sjimharris      &this_request->parent.state_machine,
1215230557Sjimharris      SCI_BASE_REQUEST_STATE_CONSTRUCTED
1216230557Sjimharris   );
1217230557Sjimharris
1218230557Sjimharris   return SCI_SUCCESS;
1219230557Sjimharris}
1220230557Sjimharris
1221230557Sjimharris// ---------------------------------------------------------------------------
1222230557Sjimharris
1223230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT)
1224230557Sjimharris
1225230557SjimharrisSCI_STATUS scic_task_request_construct_ssp(
1226230557Sjimharris   SCI_TASK_REQUEST_HANDLE_T  scic_task_request
1227230557Sjimharris)
1228230557Sjimharris{
1229230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)
1230230557Sjimharris                                      scic_task_request;
1231230557Sjimharris
1232230557Sjimharris   SCIC_LOG_TRACE((
1233230557Sjimharris      sci_base_object_get_logger(this_request),
1234230557Sjimharris      SCIC_LOG_OBJECT_SSP_IO_REQUEST,
1235230557Sjimharris      "scic_task_request_construct_ssp(0x%x) enter\n",
1236230557Sjimharris      this_request
1237230557Sjimharris   ));
1238230557Sjimharris
1239230557Sjimharris   // Construct the SSP Task SCU Task Context
1240230557Sjimharris   scu_ssp_task_request_construct_task_context(this_request);
1241230557Sjimharris
1242230557Sjimharris   // Fill in the SSP Task IU
1243230557Sjimharris   scic_sds_task_request_build_ssp_task_iu(this_request);
1244230557Sjimharris
1245230557Sjimharris   scic_sds_request_initialize_state_logging(this_request);
1246230557Sjimharris
1247230557Sjimharris   sci_base_state_machine_change_state(
1248230557Sjimharris      &this_request->parent.state_machine,
1249230557Sjimharris      SCI_BASE_REQUEST_STATE_CONSTRUCTED
1250230557Sjimharris   );
1251230557Sjimharris
1252230557Sjimharris   return SCI_SUCCESS;
1253230557Sjimharris}
1254230557Sjimharris
1255230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT)
1256230557Sjimharris
1257230557Sjimharris// ---------------------------------------------------------------------------
1258230557Sjimharris
1259230557SjimharrisSCI_STATUS scic_io_request_construct_advanced_ssp(
1260230557Sjimharris   SCI_IO_REQUEST_HANDLE_T    scic_io_request,
1261230557Sjimharris   SCIC_IO_SSP_PARAMETERS_T * io_parameters
1262230557Sjimharris)
1263230557Sjimharris{
1264230557Sjimharris   SCIC_LOG_TRACE((
1265230557Sjimharris      sci_base_object_get_logger(scic_io_request),
1266230557Sjimharris      SCIC_LOG_OBJECT_SSP_IO_REQUEST,
1267230557Sjimharris      "scic_io_request_construct_advanced_ssp(0x%x, 0x%x) enter\n",
1268230557Sjimharris      io_parameters, scic_io_request
1269230557Sjimharris   ));
1270230557Sjimharris
1271230557Sjimharris   /// @todo Implement after 1.1
1272230557Sjimharris   return SCI_FAILURE;
1273230557Sjimharris}
1274230557Sjimharris
1275230557Sjimharris// ---------------------------------------------------------------------------
1276230557Sjimharris
1277230557Sjimharris#if !defined(DISABLE_PASS_THROUGH)
1278230557SjimharrisSCI_STATUS scic_io_request_construct_ssp_pass_through (
1279230557Sjimharris   void                    * scic_io_request,
1280230557Sjimharris   SCIC_SSP_PASSTHRU_REQUEST_CALLBACKS_T *ssp_passthru_cb
1281230557Sjimharris)
1282230557Sjimharris{
1283230557Sjimharris   SCI_STATUS               status = SCI_SUCCESS;
1284230557Sjimharris   SCIC_SDS_REQUEST_T       * this_request;
1285230557Sjimharris
1286230557Sjimharris   this_request = (SCIC_SDS_REQUEST_T * )scic_io_request;
1287230557Sjimharris
1288230557Sjimharris   SCIC_LOG_TRACE((
1289230557Sjimharris      sci_base_object_get_logger(scic_io_request),
1290230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
1291230557Sjimharris      "scic_io_request_construct_ssp_pass_through(0x%x) enter\n",
1292230557Sjimharris      scic_io_request
1293230557Sjimharris   ));
1294230557Sjimharris
1295230557Sjimharris   //build the task context from the pass through buffer
1296230557Sjimharris   scu_ssp_io_request_construct_task_context(
1297230557Sjimharris      this_request,
1298230557Sjimharris      ssp_passthru_cb->common_callbacks.scic_cb_passthru_get_data_direction (this_request),
1299230557Sjimharris      ssp_passthru_cb->common_callbacks.scic_cb_passthru_get_transfer_length(this_request)
1300230557Sjimharris   );
1301230557Sjimharris
1302230557Sjimharris   //build the ssp command iu from the pass through buffer
1303230557Sjimharris   status = scic_sds_io_request_build_ssp_command_iu_pass_through (
1304230557Sjimharris               this_request,
1305230557Sjimharris               ssp_passthru_cb
1306230557Sjimharris            );
1307230557Sjimharris   if (status != SCI_SUCCESS)
1308230557Sjimharris   {
1309230557Sjimharris      return status;
1310230557Sjimharris   }
1311230557Sjimharris
1312230557Sjimharris   /* initialize the logging */
1313230557Sjimharris   scic_sds_request_initialize_state_logging(this_request);
1314230557Sjimharris
1315230557Sjimharris   sci_base_state_machine_change_state(
1316230557Sjimharris      &this_request->parent.state_machine,
1317230557Sjimharris      SCI_BASE_REQUEST_STATE_CONSTRUCTED
1318230557Sjimharris   );
1319230557Sjimharris
1320230557Sjimharris   return status;
1321230557Sjimharris}
1322230557Sjimharris#endif // !defined(DISABLE_PASS_THROUGH)
1323230557Sjimharris
1324230557Sjimharris// ---------------------------------------------------------------------------
1325230557Sjimharris
1326230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT)
1327230557Sjimharris
1328230557SjimharrisSCI_STATUS scic_task_request_construct_sata(
1329230557Sjimharris   SCI_TASK_REQUEST_HANDLE_T scic_task_request
1330230557Sjimharris)
1331230557Sjimharris{
1332230557Sjimharris   SCI_STATUS           status;
1333230557Sjimharris   SCIC_SDS_REQUEST_T * this_request;
1334230557Sjimharris   U8                   sat_protocol;
1335230557Sjimharris
1336230557Sjimharris   this_request = (SCIC_SDS_REQUEST_T *)scic_task_request;
1337230557Sjimharris
1338230557Sjimharris   SCIC_LOG_TRACE((
1339230557Sjimharris      sci_base_object_get_logger(this_request),
1340230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
1341230557Sjimharris      "scic_task_request_construct_sata(0x%x) enter\n",
1342230557Sjimharris      this_request
1343230557Sjimharris   ));
1344230557Sjimharris
1345230557Sjimharris   sat_protocol =
1346230557Sjimharris      scic_cb_request_get_sat_protocol(this_request->user_request);
1347230557Sjimharris
1348230557Sjimharris   this_request->sat_protocol = sat_protocol;
1349230557Sjimharris
1350230557Sjimharris   switch (sat_protocol)
1351230557Sjimharris   {
1352230557Sjimharris   case SAT_PROTOCOL_ATA_HARD_RESET:
1353230557Sjimharris   case SAT_PROTOCOL_SOFT_RESET:
1354230557Sjimharris      status = scic_sds_stp_soft_reset_request_construct(this_request);
1355230557Sjimharris      break;
1356230557Sjimharris
1357230557Sjimharris   case SAT_PROTOCOL_PIO_DATA_IN:
1358230557Sjimharris      status = scic_sds_stp_pio_request_construct(this_request, sat_protocol, FALSE);
1359230557Sjimharris      break;
1360230557Sjimharris
1361230557Sjimharris   default:
1362230557Sjimharris      SCIC_LOG_ERROR((
1363230557Sjimharris         sci_base_object_get_logger(this_request),
1364230557Sjimharris         SCIC_LOG_OBJECT_STP_IO_REQUEST,
1365230557Sjimharris         "SCIC IO Request 0x%x received un-handled SAT Protocl %d.\n",
1366230557Sjimharris         this_request, sat_protocol
1367230557Sjimharris      ));
1368230557Sjimharris
1369230557Sjimharris      status = SCI_FAILURE;
1370230557Sjimharris      break;
1371230557Sjimharris   }
1372230557Sjimharris
1373230557Sjimharris   if (status == SCI_SUCCESS)
1374230557Sjimharris   {
1375230557Sjimharris      scic_sds_request_initialize_state_logging(this_request);
1376230557Sjimharris
1377230557Sjimharris      sci_base_state_machine_change_state(
1378230557Sjimharris         &this_request->parent.state_machine,
1379230557Sjimharris         SCI_BASE_REQUEST_STATE_CONSTRUCTED
1380230557Sjimharris      );
1381230557Sjimharris   }
1382230557Sjimharris
1383230557Sjimharris   return status;
1384230557Sjimharris}
1385230557Sjimharris
1386230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT)
1387230557Sjimharris
1388230557Sjimharris// ---------------------------------------------------------------------------
1389230557Sjimharris
1390230557Sjimharris#if !defined(DISABLE_PASS_THROUGH)
1391230557SjimharrisSCI_STATUS scic_io_request_construct_sata_pass_through(
1392230557Sjimharris   SCI_IO_REQUEST_HANDLE_T scic_io_request,
1393230557Sjimharris   SCIC_STP_PASSTHRU_REQUEST_CALLBACKS_T *passthru_cb
1394230557Sjimharris)
1395230557Sjimharris{
1396230557Sjimharris   SCI_STATUS                       status = SCI_SUCCESS;
1397230557Sjimharris   SCIC_SDS_REQUEST_T               * this_request;
1398230557Sjimharris   U8                               sat_protocol;
1399230557Sjimharris   U8                               * reg_fis;
1400230557Sjimharris   U32                              transfer_length;
1401230557Sjimharris   SCI_IO_REQUEST_DATA_DIRECTION    data_direction;
1402230557Sjimharris
1403230557Sjimharris   this_request = (SCIC_SDS_REQUEST_T * )scic_io_request;
1404230557Sjimharris
1405230557Sjimharris   SCIC_LOG_TRACE((
1406230557Sjimharris      sci_base_object_get_logger(scic_io_request),
1407230557Sjimharris      SCIC_LOG_OBJECT_STP_IO_REQUEST,
1408230557Sjimharris      "scic_io_request_construct_sata_pass_through(0x%x) enter\n",
1409230557Sjimharris      scic_io_request
1410230557Sjimharris   ));
1411230557Sjimharris
1412230557Sjimharris   passthru_cb->scic_cb_stp_passthru_get_register_fis(this_request, &reg_fis);
1413230557Sjimharris
1414230557Sjimharris   if (reg_fis == NULL)
1415230557Sjimharris   {
1416230557Sjimharris      status = SCI_FAILURE_INVALID_PARAMETER_VALUE;
1417230557Sjimharris   }
1418230557Sjimharris
1419230557Sjimharris   if (status == SCI_SUCCESS)
1420230557Sjimharris   {
1421230557Sjimharris      //copy the H2D Reg fis blindly from the request to the SCU command buffer
1422230557Sjimharris      memcpy ((U8 *)this_request->command_buffer, (U8 *)reg_fis, sizeof(SATA_FIS_REG_H2D_T));
1423230557Sjimharris
1424230557Sjimharris      //continue to create the request
1425230557Sjimharris      sat_protocol = passthru_cb->scic_cb_stp_passthru_get_protocol(this_request);
1426230557Sjimharris      transfer_length = passthru_cb->common_callbacks.scic_cb_passthru_get_transfer_length(this_request);
1427230557Sjimharris      data_direction = passthru_cb->common_callbacks.scic_cb_passthru_get_data_direction(this_request);
1428230557Sjimharris
1429230557Sjimharris      status = scic_sds_io_request_construct_sata(
1430230557Sjimharris                  this_request,
1431230557Sjimharris                  sat_protocol,
1432230557Sjimharris                  transfer_length,
1433230557Sjimharris                  data_direction,
1434230557Sjimharris                  TRUE,
1435230557Sjimharris                  TRUE
1436230557Sjimharris               );
1437230557Sjimharris
1438230557Sjimharris      this_request->protocol = SCIC_STP_PROTOCOL;
1439230557Sjimharris   }
1440230557Sjimharris
1441230557Sjimharris   return status;
1442230557Sjimharris}
1443230557Sjimharris#endif // !defined(DISABLE_PASS_THROUGH)
1444230557Sjimharris
1445230557Sjimharris// ---------------------------------------------------------------------------
1446230557Sjimharris
1447230557SjimharrisU16 scic_io_request_get_io_tag(
1448230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  scic_io_request
1449230557Sjimharris)
1450230557Sjimharris{
1451230557Sjimharris   SCIC_SDS_REQUEST_T *this_request;
1452230557Sjimharris   this_request = (SCIC_SDS_REQUEST_T *)scic_io_request;
1453230557Sjimharris
1454230557Sjimharris   SCIC_LOG_TRACE((
1455230557Sjimharris      sci_base_object_get_logger(scic_io_request),
1456230557Sjimharris      SCIC_LOG_OBJECT_SMP_IO_REQUEST,
1457230557Sjimharris      "scic_io_request_get_io_tag(0x%x) enter\n",
1458230557Sjimharris      scic_io_request
1459230557Sjimharris   ));
1460230557Sjimharris
1461230557Sjimharris   return this_request->io_tag;
1462230557Sjimharris}
1463230557Sjimharris
1464230557Sjimharris// ---------------------------------------------------------------------------
1465230557Sjimharris
1466230557SjimharrisU32 scic_request_get_controller_status(
1467230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  io_request
1468230557Sjimharris)
1469230557Sjimharris{
1470230557Sjimharris   SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T*)io_request;
1471230557Sjimharris   return this_request->scu_status;
1472230557Sjimharris}
1473230557Sjimharris
1474230557SjimharrisU32 scic_request_get_sci_status(
1475230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  io_request
1476230557Sjimharris)
1477230557Sjimharris{
1478230557Sjimharris   SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T*)io_request;
1479230557Sjimharris   return this_request->sci_status;
1480230557Sjimharris}
1481230557Sjimharris
1482230557Sjimharris// ---------------------------------------------------------------------------
1483230557Sjimharris
1484230557Sjimharrisvoid * scic_io_request_get_rx_frame(
1485230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  scic_io_request,
1486230557Sjimharris   U32                      offset
1487230557Sjimharris)
1488230557Sjimharris{
1489230557Sjimharris   void               * frame_buffer = NULL;
1490230557Sjimharris   SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request;
1491230557Sjimharris
1492230557Sjimharris   ASSERT(offset < SCU_UNSOLICITED_FRAME_BUFFER_SIZE);
1493230557Sjimharris
1494230557Sjimharris   if (this_request->saved_rx_frame_index != SCU_INVALID_FRAME_INDEX)
1495230557Sjimharris   {
1496230557Sjimharris      scic_sds_unsolicited_frame_control_get_buffer(
1497230557Sjimharris         &(this_request->owning_controller->uf_control),
1498230557Sjimharris         this_request->saved_rx_frame_index,
1499230557Sjimharris         &frame_buffer
1500230557Sjimharris      );
1501230557Sjimharris   }
1502230557Sjimharris
1503230557Sjimharris   return frame_buffer;
1504230557Sjimharris}
1505230557Sjimharris
1506230557Sjimharrisvoid * scic_io_request_get_command_iu_address(
1507230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  scic_io_request
1508230557Sjimharris)
1509230557Sjimharris{
1510230557Sjimharris   SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request;
1511230557Sjimharris
1512230557Sjimharris   return this_request->command_buffer;
1513230557Sjimharris}
1514230557Sjimharris
1515230557Sjimharris// ---------------------------------------------------------------------------
1516230557Sjimharris
1517230557Sjimharrisvoid * scic_io_request_get_response_iu_address(
1518230557Sjimharris   SCI_IO_REQUEST_HANDLE_T scic_io_request
1519230557Sjimharris)
1520230557Sjimharris{
1521230557Sjimharris   SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request;
1522230557Sjimharris
1523230557Sjimharris   return this_request->response_buffer;
1524230557Sjimharris}
1525230557Sjimharris
1526230557Sjimharris// ---------------------------------------------------------------------------
1527230557Sjimharris#define SCU_TASK_CONTEXT_SRAM 0x200000
1528230557SjimharrisU32 scic_io_request_get_number_of_bytes_transferred (
1529230557Sjimharris   SCI_IO_REQUEST_HANDLE_T  scic_io_request
1530230557Sjimharris)
1531230557Sjimharris{
1532230557Sjimharris   U32 ret_val = 0;
1533230557Sjimharris   SCIC_SDS_REQUEST_T       * scic_sds_request;
1534230557Sjimharris
1535230557Sjimharris   scic_sds_request = (SCIC_SDS_REQUEST_T *) scic_io_request;
1536230557Sjimharris
1537230557Sjimharris   if ( SMU_AMR_READ (scic_sds_request->owning_controller) == 0)
1538230557Sjimharris   {
1539230557Sjimharris      //get the bytes of data from the Address == BAR1 + 20002Ch + (256*TCi) where
1540230557Sjimharris      //   BAR1 is the scu_registers
1541230557Sjimharris      //   0x20002C = 0x200000 + 0x2c
1542230557Sjimharris      //            = start of task context SRAM + offset of (type.ssp.data_offset)
1543230557Sjimharris      //   TCi is the io_tag of SCIC_SDS_REQUEST
1544230557Sjimharris      ret_val =  scic_sds_pci_read_scu_dword(
1545230557Sjimharris                    scic_sds_request->owning_controller,
1546230557Sjimharris                    (
1547230557Sjimharris                       (U8 *) scic_sds_request->owning_controller->scu_registers +
1548230557Sjimharris                          ( SCU_TASK_CONTEXT_SRAM + SCI_FIELD_OFFSET(SCU_TASK_CONTEXT_T, type.ssp.data_offset) ) +
1549230557Sjimharris                       ( ( sizeof (SCU_TASK_CONTEXT_T) ) * scic_sds_io_tag_get_index (scic_sds_request->io_tag))
1550230557Sjimharris                    )
1551230557Sjimharris                 );
1552230557Sjimharris   }
1553230557Sjimharris
1554230557Sjimharris   return ret_val;
1555230557Sjimharris}
1556230557Sjimharris
1557230557Sjimharris//****************************************************************************
1558230557Sjimharris//* SCIC SDS Interface Implementation
1559230557Sjimharris//****************************************************************************
1560230557Sjimharris
1561230557Sjimharris/**
1562230557Sjimharris * This method invokes the base state start request handler for the
1563230557Sjimharris * SCIC_SDS_IO_REQUEST_T object.
1564230557Sjimharris *
1565230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the
1566230557Sjimharris *       start operation is to be executed.
1567230557Sjimharris *
1568230557Sjimharris * @return SCI_STATUS
1569230557Sjimharris */
1570230557SjimharrisSCI_STATUS scic_sds_request_start(
1571230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
1572230557Sjimharris)
1573230557Sjimharris{
1574230557Sjimharris   if (
1575230557Sjimharris         this_request->device_sequence
1576230557Sjimharris      == scic_sds_remote_device_get_sequence(this_request->target_device)
1577230557Sjimharris      )
1578230557Sjimharris   {
1579230557Sjimharris      return this_request->state_handlers->parent.start_handler(
1580230557Sjimharris                &this_request->parent
1581230557Sjimharris             );
1582230557Sjimharris   }
1583230557Sjimharris
1584230557Sjimharris   return SCI_FAILURE;
1585230557Sjimharris}
1586230557Sjimharris
1587230557Sjimharris/**
1588230557Sjimharris * This method invokes the base state terminate request handber for the
1589230557Sjimharris * SCIC_SDS_IO_REQUEST_T object.
1590230557Sjimharris *
1591230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the
1592230557Sjimharris *       start operation is to be executed.
1593230557Sjimharris *
1594230557Sjimharris * @return SCI_STATUS
1595230557Sjimharris */
1596230557SjimharrisSCI_STATUS scic_sds_io_request_terminate(
1597230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
1598230557Sjimharris)
1599230557Sjimharris{
1600230557Sjimharris   return this_request->state_handlers->parent.abort_handler(
1601230557Sjimharris                                                      &this_request->parent);
1602230557Sjimharris}
1603230557Sjimharris
1604230557Sjimharris/**
1605230557Sjimharris * This method invokes the base state request completion handler for the
1606230557Sjimharris * SCIC_SDS_IO_REQUEST_T object.
1607230557Sjimharris *
1608230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the
1609230557Sjimharris *       start operation is to be executed.
1610230557Sjimharris *
1611230557Sjimharris * @return SCI_STATUS
1612230557Sjimharris */
1613230557SjimharrisSCI_STATUS scic_sds_io_request_complete(
1614230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
1615230557Sjimharris)
1616230557Sjimharris{
1617230557Sjimharris   return this_request->state_handlers->parent.complete_handler(
1618230557Sjimharris                                                      &this_request->parent);
1619230557Sjimharris}
1620230557Sjimharris
1621230557Sjimharris/**
1622230557Sjimharris * This method invokes the core state handler for the SCIC_SDS_IO_REQUEST_T
1623230557Sjimharris * object.
1624230557Sjimharris *
1625230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the
1626230557Sjimharris *       start operation is to be executed.
1627230557Sjimharris * @param[in] event_code The event code returned by the hardware for the task
1628230557Sjimharris *       reqeust.
1629230557Sjimharris *
1630230557Sjimharris * @return SCI_STATUS
1631230557Sjimharris */
1632230557SjimharrisSCI_STATUS scic_sds_io_request_event_handler(
1633230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
1634230557Sjimharris   U32                  event_code
1635230557Sjimharris)
1636230557Sjimharris{
1637230557Sjimharris   return this_request->state_handlers->event_handler(this_request, event_code);
1638230557Sjimharris}
1639230557Sjimharris
1640230557Sjimharris/**
1641230557Sjimharris * This method invokes the core state frame handler for the
1642230557Sjimharris * SCIC_SDS_IO_REQUEST_T object.
1643230557Sjimharris *
1644230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the
1645230557Sjimharris *       start operation is to be executed.
1646230557Sjimharris * @param[in] frame_index The frame index returned by the hardware for the
1647230557Sjimharris *       reqeust object.
1648230557Sjimharris *
1649230557Sjimharris * @return SCI_STATUS
1650230557Sjimharris */
1651230557SjimharrisSCI_STATUS scic_sds_io_request_frame_handler(
1652230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
1653230557Sjimharris   U32                  frame_index
1654230557Sjimharris)
1655230557Sjimharris{
1656230557Sjimharris   return this_request->state_handlers->frame_handler(this_request, frame_index);
1657230557Sjimharris}
1658230557Sjimharris
1659230557Sjimharris/**
1660230557Sjimharris * This method invokes the core state task complete handler for the
1661230557Sjimharris * SCIC_SDS_IO_REQUEST_T object.
1662230557Sjimharris *
1663230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the task
1664230557Sjimharris *       start operation is to be executed.
1665230557Sjimharris *
1666230557Sjimharris * @return SCI_STATUS
1667230557Sjimharris */
1668230557SjimharrisSCI_STATUS scic_sds_task_request_complete(
1669230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
1670230557Sjimharris)
1671230557Sjimharris{
1672230557Sjimharris   return this_request->state_handlers->parent.complete_handler(&this_request->parent);
1673230557Sjimharris}
1674230557Sjimharris
1675230557Sjimharris//****************************************************************************
1676230557Sjimharris//* SCIC SDS PROTECTED METHODS
1677230557Sjimharris//****************************************************************************
1678230557Sjimharris
1679230557Sjimharris/**
1680230557Sjimharris * @brief This method copies response data for requests returning response
1681230557Sjimharris *        data instead of sense data.
1682230557Sjimharris *
1683230557Sjimharris * @param[in]  this_request This parameter specifies the request object for
1684230557Sjimharris *             which to copy the response data.
1685230557Sjimharris *
1686230557Sjimharris * @return none
1687230557Sjimharris */
1688230557Sjimharrisvoid scic_sds_io_request_copy_response(
1689230557Sjimharris   SCIC_SDS_REQUEST_T *this_request
1690230557Sjimharris)
1691230557Sjimharris{
1692230557Sjimharris   void                  * response_buffer;
1693230557Sjimharris   U32                     user_response_length;
1694230557Sjimharris   U32                     core_response_length;
1695230557Sjimharris   SCI_SSP_RESPONSE_IU_T * ssp_response;
1696230557Sjimharris
1697230557Sjimharris   ssp_response = (SCI_SSP_RESPONSE_IU_T *)this_request->response_buffer;
1698230557Sjimharris
1699230557Sjimharris   response_buffer = scic_cb_ssp_task_request_get_response_data_address(
1700230557Sjimharris                        this_request->user_request
1701230557Sjimharris                     );
1702230557Sjimharris
1703230557Sjimharris   user_response_length = scic_cb_ssp_task_request_get_response_data_length(
1704230557Sjimharris                        this_request->user_request
1705230557Sjimharris                     );
1706230557Sjimharris
1707230557Sjimharris   core_response_length = sci_ssp_get_response_data_length(
1708230557Sjimharris                           ssp_response->response_data_length
1709230557Sjimharris                     );
1710230557Sjimharris
1711230557Sjimharris   user_response_length = MIN(user_response_length, core_response_length);
1712230557Sjimharris
1713230557Sjimharris   memcpy(response_buffer, ssp_response->data, user_response_length);
1714230557Sjimharris}
1715230557Sjimharris
1716230557Sjimharris//******************************************************************************
1717230557Sjimharris//* REQUEST STATE MACHINE
1718230557Sjimharris//******************************************************************************
1719230557Sjimharris
1720230557Sjimharris//*****************************************************************************
1721230557Sjimharris//*  DEFAULT STATE HANDLERS
1722230557Sjimharris//*****************************************************************************
1723230557Sjimharris
1724230557Sjimharris/**
1725230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1726230557Sjimharris * object receives a scic_sds_request_start() request.  The default action is
1727230557Sjimharris * to log a warning and return a failure status.
1728230557Sjimharris *
1729230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
1730230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
1731230557Sjimharris *       requested.
1732230557Sjimharris *
1733230557Sjimharris * @return SCI_STATUS
1734230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE
1735230557Sjimharris */
1736230557SjimharrisSCI_STATUS scic_sds_request_default_start_handler(
1737230557Sjimharris   SCI_BASE_REQUEST_T *request
1738230557Sjimharris)
1739230557Sjimharris{
1740230557Sjimharris   SCIC_LOG_WARNING((
1741230557Sjimharris      sci_base_object_get_logger((SCIC_SDS_REQUEST_T *)request),
1742230557Sjimharris      (
1743230557Sjimharris          SCIC_LOG_OBJECT_SSP_IO_REQUEST
1744230557Sjimharris        | SCIC_LOG_OBJECT_STP_IO_REQUEST
1745230557Sjimharris        | SCIC_LOG_OBJECT_SMP_IO_REQUEST
1746230557Sjimharris      ),
1747230557Sjimharris      "SCIC IO Request requested to start while in wrong state %d\n",
1748230557Sjimharris      sci_base_state_machine_get_state(
1749230557Sjimharris         &((SCIC_SDS_REQUEST_T *)request)->parent.state_machine)
1750230557Sjimharris   ));
1751230557Sjimharris
1752230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
1753230557Sjimharris}
1754230557Sjimharris
1755230557Sjimharris/**
1756230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1757230557Sjimharris * object receives a scic_sds_request_terminate() request.  The default action
1758230557Sjimharris * is to log a warning and return a failure status.
1759230557Sjimharris *
1760230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
1761230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
1762230557Sjimharris *       requested.
1763230557Sjimharris *
1764230557Sjimharris * @return SCI_STATUS
1765230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE
1766230557Sjimharris */
1767230557SjimharrisSCI_STATUS scic_sds_request_default_abort_handler(
1768230557Sjimharris   SCI_BASE_REQUEST_T *request
1769230557Sjimharris)
1770230557Sjimharris{
1771230557Sjimharris   SCIC_LOG_WARNING((
1772230557Sjimharris      sci_base_object_get_logger((SCIC_SDS_REQUEST_T *)request),
1773230557Sjimharris      (
1774230557Sjimharris          SCIC_LOG_OBJECT_SSP_IO_REQUEST
1775230557Sjimharris        | SCIC_LOG_OBJECT_STP_IO_REQUEST
1776230557Sjimharris        | SCIC_LOG_OBJECT_SMP_IO_REQUEST
1777230557Sjimharris      ),
1778230557Sjimharris      "SCIC IO Request requested to abort while in wrong state %d\n",
1779230557Sjimharris      sci_base_state_machine_get_state(
1780230557Sjimharris         &((SCIC_SDS_REQUEST_T *)request)->parent.state_machine)
1781230557Sjimharris   ));
1782230557Sjimharris
1783230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
1784230557Sjimharris}
1785230557Sjimharris
1786230557Sjimharris/**
1787230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1788230557Sjimharris * object receives a scic_sds_request_complete() request.  The default action
1789230557Sjimharris * is to log a warning and return a failure status.
1790230557Sjimharris *
1791230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
1792230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
1793230557Sjimharris *       requested.
1794230557Sjimharris *
1795230557Sjimharris * @return SCI_STATUS
1796230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE
1797230557Sjimharris */
1798230557SjimharrisSCI_STATUS scic_sds_request_default_complete_handler(
1799230557Sjimharris   SCI_BASE_REQUEST_T *request
1800230557Sjimharris)
1801230557Sjimharris{
1802230557Sjimharris   SCIC_LOG_WARNING((
1803230557Sjimharris      sci_base_object_get_logger((SCIC_SDS_REQUEST_T *)request),
1804230557Sjimharris      (
1805230557Sjimharris          SCIC_LOG_OBJECT_SSP_IO_REQUEST
1806230557Sjimharris        | SCIC_LOG_OBJECT_STP_IO_REQUEST
1807230557Sjimharris        | SCIC_LOG_OBJECT_SMP_IO_REQUEST
1808230557Sjimharris      ),
1809230557Sjimharris      "SCIC IO Request requested to complete while in wrong state %d\n",
1810230557Sjimharris      sci_base_state_machine_get_state(
1811230557Sjimharris         &((SCIC_SDS_REQUEST_T *)request)->parent.state_machine)
1812230557Sjimharris   ));
1813230557Sjimharris
1814230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
1815230557Sjimharris}
1816230557Sjimharris
1817230557Sjimharris/**
1818230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1819230557Sjimharris * object receives a scic_sds_request_complete() request.  The default action
1820230557Sjimharris * is to log a warning and return a failure status.
1821230557Sjimharris *
1822230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
1823230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
1824230557Sjimharris *       requested.
1825230557Sjimharris *
1826230557Sjimharris * @return SCI_STATUS
1827230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE
1828230557Sjimharris */
1829230557SjimharrisSCI_STATUS scic_sds_request_default_destruct_handler(
1830230557Sjimharris   SCI_BASE_REQUEST_T *request
1831230557Sjimharris)
1832230557Sjimharris{
1833230557Sjimharris   SCIC_LOG_WARNING((
1834230557Sjimharris      sci_base_object_get_logger((SCIC_SDS_REQUEST_T *)request),
1835230557Sjimharris      (
1836230557Sjimharris          SCIC_LOG_OBJECT_SSP_IO_REQUEST
1837230557Sjimharris        | SCIC_LOG_OBJECT_STP_IO_REQUEST
1838230557Sjimharris        | SCIC_LOG_OBJECT_SMP_IO_REQUEST
1839230557Sjimharris      ),
1840230557Sjimharris      "SCIC IO Request requested to destroy while in wrong state %d\n",
1841230557Sjimharris      sci_base_state_machine_get_state(
1842230557Sjimharris         &((SCIC_SDS_REQUEST_T *)request)->parent.state_machine)
1843230557Sjimharris   ));
1844230557Sjimharris
1845230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
1846230557Sjimharris}
1847230557Sjimharris
1848230557Sjimharris/**
1849230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1850230557Sjimharris * object receives a scic_sds_task_request_complete() request.  The default
1851230557Sjimharris * action is to log a warning and return a failure status.
1852230557Sjimharris *
1853230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
1854230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
1855230557Sjimharris *       requested.
1856230557Sjimharris *
1857230557Sjimharris * @return SCI_STATUS
1858230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE
1859230557Sjimharris */
1860230557SjimharrisSCI_STATUS scic_sds_request_default_tc_completion_handler(
1861230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
1862230557Sjimharris   U32                  completion_code
1863230557Sjimharris)
1864230557Sjimharris{
1865230557Sjimharris   SCIC_LOG_WARNING((
1866230557Sjimharris      sci_base_object_get_logger(this_request),
1867230557Sjimharris      (
1868230557Sjimharris          SCIC_LOG_OBJECT_SSP_IO_REQUEST
1869230557Sjimharris        | SCIC_LOG_OBJECT_STP_IO_REQUEST
1870230557Sjimharris        | SCIC_LOG_OBJECT_SMP_IO_REQUEST
1871230557Sjimharris      ),
1872230557Sjimharris      "SCIC IO Request given task completion notification %x while in wrong state %d\n",
1873230557Sjimharris      completion_code,
1874230557Sjimharris      sci_base_state_machine_get_state(&this_request->parent.state_machine)
1875230557Sjimharris   ));
1876230557Sjimharris
1877230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
1878230557Sjimharris
1879230557Sjimharris}
1880230557Sjimharris
1881230557Sjimharris/**
1882230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1883230557Sjimharris * object receives a scic_sds_request_event_handler() request.  The default
1884230557Sjimharris * action is to log a warning and return a failure status.
1885230557Sjimharris *
1886230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
1887230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
1888230557Sjimharris *       requested.
1889230557Sjimharris *
1890230557Sjimharris * @return SCI_STATUS
1891230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE
1892230557Sjimharris */
1893230557SjimharrisSCI_STATUS scic_sds_request_default_event_handler(
1894230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
1895230557Sjimharris   U32                  event_code
1896230557Sjimharris)
1897230557Sjimharris{
1898230557Sjimharris   SCIC_LOG_WARNING((
1899230557Sjimharris      sci_base_object_get_logger(this_request),
1900230557Sjimharris      (
1901230557Sjimharris          SCIC_LOG_OBJECT_SSP_IO_REQUEST
1902230557Sjimharris        | SCIC_LOG_OBJECT_STP_IO_REQUEST
1903230557Sjimharris        | SCIC_LOG_OBJECT_SMP_IO_REQUEST
1904230557Sjimharris      ),
1905230557Sjimharris      "SCIC IO Request given event code notification %x while in wrong state %d\n",
1906230557Sjimharris      event_code,
1907230557Sjimharris      sci_base_state_machine_get_state(&this_request->parent.state_machine)
1908230557Sjimharris   ));
1909230557Sjimharris
1910230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
1911230557Sjimharris}
1912230557Sjimharris
1913230557Sjimharris/**
1914230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1915230557Sjimharris * object receives a scic_sds_request_event_handler() request.  The default
1916230557Sjimharris * action is to log a warning and return a failure status.
1917230557Sjimharris *
1918230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
1919230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
1920230557Sjimharris *       requested.
1921230557Sjimharris *
1922230557Sjimharris * @return SCI_STATUS
1923230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE
1924230557Sjimharris */
1925230557SjimharrisSCI_STATUS scic_sds_request_default_frame_handler(
1926230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
1927230557Sjimharris   U32                  frame_index
1928230557Sjimharris)
1929230557Sjimharris{
1930230557Sjimharris   SCIC_LOG_WARNING((
1931230557Sjimharris      sci_base_object_get_logger(this_request),
1932230557Sjimharris      (
1933230557Sjimharris          SCIC_LOG_OBJECT_SSP_IO_REQUEST
1934230557Sjimharris        | SCIC_LOG_OBJECT_STP_IO_REQUEST
1935230557Sjimharris        | SCIC_LOG_OBJECT_SMP_IO_REQUEST
1936230557Sjimharris      ),
1937230557Sjimharris      "SCIC IO Request given unexpected frame %x while in state %d\n",
1938230557Sjimharris      frame_index,
1939230557Sjimharris      sci_base_state_machine_get_state(&this_request->parent.state_machine)
1940230557Sjimharris   ));
1941230557Sjimharris
1942230557Sjimharris   scic_sds_controller_release_frame(
1943230557Sjimharris      this_request->owning_controller, frame_index);
1944230557Sjimharris
1945230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
1946230557Sjimharris}
1947230557Sjimharris
1948230557Sjimharris//*****************************************************************************
1949230557Sjimharris//*  CONSTRUCTED STATE HANDLERS
1950230557Sjimharris//*****************************************************************************
1951230557Sjimharris
1952230557Sjimharris/**
1953230557Sjimharris * This method implements the action taken when a constructed
1954230557Sjimharris * SCIC_SDS_IO_REQUEST_T object receives a scic_sds_request_start() request.
1955230557Sjimharris *
1956230557Sjimharris * This method will, if necessary, allocate a TCi for the io request object
1957230557Sjimharris * and then will, if necessary, copy the constructed TC data into the actual
1958230557Sjimharris * TC buffer.  If everything is successful the post context field is updated
1959230557Sjimharris * with the TCi so the controller can post the request to the hardware.
1960230557Sjimharris *
1961230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
1962230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
1963230557Sjimharris *       requested.
1964230557Sjimharris *
1965230557Sjimharris * @return SCI_STATUS
1966230557Sjimharris * @retval SCI_SUCCESS
1967230557Sjimharris * @retval SCI_FAILURE_INSUFFICIENT_RESOURCES
1968230557Sjimharris */
1969230557Sjimharrisstatic
1970230557SjimharrisSCI_STATUS scic_sds_request_constructed_state_start_handler(
1971230557Sjimharris   SCI_BASE_REQUEST_T *request
1972230557Sjimharris)
1973230557Sjimharris{
1974230557Sjimharris   SCU_TASK_CONTEXT_T *task_context;
1975230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request;
1976230557Sjimharris
1977230557Sjimharris   if (this_request->io_tag == SCI_CONTROLLER_INVALID_IO_TAG)
1978230557Sjimharris   {
1979230557Sjimharris      this_request->io_tag =
1980230557Sjimharris         scic_controller_allocate_io_tag(this_request->owning_controller);
1981230557Sjimharris   }
1982230557Sjimharris
1983230557Sjimharris   // Record the IO Tag in the request
1984230557Sjimharris   if (this_request->io_tag != SCI_CONTROLLER_INVALID_IO_TAG)
1985230557Sjimharris   {
1986230557Sjimharris      task_context = this_request->task_context_buffer;
1987230557Sjimharris
1988230557Sjimharris      task_context->task_index = scic_sds_io_tag_get_index(this_request->io_tag);
1989230557Sjimharris
1990230557Sjimharris      switch (task_context->protocol_type)
1991230557Sjimharris      {
1992230557Sjimharris      case SCU_TASK_CONTEXT_PROTOCOL_SMP:
1993230557Sjimharris      case SCU_TASK_CONTEXT_PROTOCOL_SSP:
1994230557Sjimharris         // SSP/SMP Frame
1995230557Sjimharris         task_context->type.ssp.tag = this_request->io_tag;
1996230557Sjimharris         task_context->type.ssp.target_port_transfer_tag = 0xFFFF;
1997230557Sjimharris         break;
1998230557Sjimharris
1999230557Sjimharris      case SCU_TASK_CONTEXT_PROTOCOL_STP:
2000230557Sjimharris         // STP/SATA Frame
2001230557Sjimharris         //task_context->type.stp.ncq_tag = this_request->ncq_tag;
2002230557Sjimharris         break;
2003230557Sjimharris
2004230557Sjimharris      case SCU_TASK_CONTEXT_PROTOCOL_NONE:
2005230557Sjimharris         /// @todo When do we set no protocol type?
2006230557Sjimharris         break;
2007230557Sjimharris
2008230557Sjimharris      default:
2009230557Sjimharris         // This should never happen since we build the IO requests
2010230557Sjimharris         break;
2011230557Sjimharris      }
2012230557Sjimharris
2013230557Sjimharris      // Check to see if we need to copy the task context buffer
2014230557Sjimharris      // or have been building into the task context buffer
2015230557Sjimharris      if (this_request->was_tag_assigned_by_user == FALSE)
2016230557Sjimharris      {
2017230557Sjimharris         scic_sds_controller_copy_task_context(
2018230557Sjimharris            this_request->owning_controller, this_request
2019230557Sjimharris         );
2020230557Sjimharris      }
2021230557Sjimharris
2022230557Sjimharris      // Add to the post_context the io tag value
2023230557Sjimharris      this_request->post_context |= scic_sds_io_tag_get_index(this_request->io_tag);
2024230557Sjimharris
2025230557Sjimharris      // Everything is good go ahead and change state
2026230557Sjimharris      sci_base_state_machine_change_state(
2027230557Sjimharris         &this_request->parent.state_machine,
2028230557Sjimharris         SCI_BASE_REQUEST_STATE_STARTED
2029230557Sjimharris      );
2030230557Sjimharris
2031230557Sjimharris      return SCI_SUCCESS;
2032230557Sjimharris   }
2033230557Sjimharris
2034230557Sjimharris   return SCI_FAILURE_INSUFFICIENT_RESOURCES;
2035230557Sjimharris}
2036230557Sjimharris
2037230557Sjimharris/**
2038230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
2039230557Sjimharris * object receives a scic_sds_request_terminate() request.
2040230557Sjimharris *
2041230557Sjimharris * Since the request has not yet been posted to the hardware the request
2042230557Sjimharris * transitions to the completed state.
2043230557Sjimharris *
2044230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
2045230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
2046230557Sjimharris *       requested.
2047230557Sjimharris *
2048230557Sjimharris * @return SCI_STATUS
2049230557Sjimharris * @retval SCI_SUCCESS
2050230557Sjimharris */
2051230557Sjimharrisstatic
2052230557SjimharrisSCI_STATUS scic_sds_request_constructed_state_abort_handler(
2053230557Sjimharris   SCI_BASE_REQUEST_T *request
2054230557Sjimharris)
2055230557Sjimharris{
2056230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request;
2057230557Sjimharris
2058230557Sjimharris   // This request has been terminated by the user make sure that the correct
2059230557Sjimharris   // status code is returned
2060230557Sjimharris   scic_sds_request_set_status(
2061230557Sjimharris      this_request,
2062230557Sjimharris      SCU_TASK_DONE_TASK_ABORT,
2063230557Sjimharris      SCI_FAILURE_IO_TERMINATED
2064230557Sjimharris   );
2065230557Sjimharris
2066230557Sjimharris   sci_base_state_machine_change_state(
2067230557Sjimharris      &this_request->parent.state_machine,
2068230557Sjimharris      SCI_BASE_REQUEST_STATE_COMPLETED
2069230557Sjimharris   );
2070230557Sjimharris
2071230557Sjimharris   return SCI_SUCCESS;
2072230557Sjimharris}
2073230557Sjimharris
2074230557Sjimharris//*****************************************************************************
2075230557Sjimharris//*  STARTED STATE HANDLERS
2076230557Sjimharris//*****************************************************************************
2077230557Sjimharris
2078230557Sjimharris/**
2079230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
2080230557Sjimharris * object receives a scic_sds_request_terminate() request.
2081230557Sjimharris *
2082230557Sjimharris * Since the request has been posted to the hardware the io request state is
2083230557Sjimharris * changed to the aborting state.
2084230557Sjimharris *
2085230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
2086230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
2087230557Sjimharris *       requested.
2088230557Sjimharris *
2089230557Sjimharris * @return SCI_STATUS
2090230557Sjimharris * @retval SCI_SUCCESS
2091230557Sjimharris */
2092230557SjimharrisSCI_STATUS scic_sds_request_started_state_abort_handler(
2093230557Sjimharris   SCI_BASE_REQUEST_T *request
2094230557Sjimharris)
2095230557Sjimharris{
2096230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request;
2097230557Sjimharris
2098230557Sjimharris   if (this_request->has_started_substate_machine)
2099230557Sjimharris   {
2100230557Sjimharris      sci_base_state_machine_stop(&this_request->started_substate_machine);
2101230557Sjimharris   }
2102230557Sjimharris
2103230557Sjimharris   sci_base_state_machine_change_state(
2104230557Sjimharris      &this_request->parent.state_machine,
2105230557Sjimharris      SCI_BASE_REQUEST_STATE_ABORTING
2106230557Sjimharris   );
2107230557Sjimharris
2108230557Sjimharris   return SCI_SUCCESS;
2109230557Sjimharris}
2110230557Sjimharris
2111230557Sjimharris/**
2112230557Sjimharris * @brief This method process TC (task context) completions for normal IO
2113230557Sjimharris *        request (i.e. Task/Abort Completions of type 0).  This method will
2114230557Sjimharris *        update the SCIC_SDS_IO_REQUEST_T::status field.
2115230557Sjimharris *
2116230557Sjimharris * @param[in] this_request This parameter specifies the request for which
2117230557Sjimharris *             a completion occurred.
2118230557Sjimharris * @param[in]  completion_code This parameter specifies the completion code
2119230557Sjimharris *             recieved from the SCU.
2120230557Sjimharris *
2121230557Sjimharris * @return none
2122230557Sjimharris */
2123230557SjimharrisSCI_STATUS scic_sds_request_started_state_tc_completion_handler(
2124230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
2125230557Sjimharris   U32                  completion_code
2126230557Sjimharris)
2127230557Sjimharris{
2128230557Sjimharris   U8                      data_present;
2129230557Sjimharris   SCI_SSP_RESPONSE_IU_T * response_buffer;
2130230557Sjimharris
2131230557Sjimharris   /**
2132230557Sjimharris    * @todo Any SDMA return code of other than 0 is bad
2133230557Sjimharris    *       decode 0x003C0000 to determine SDMA status
2134230557Sjimharris    */
2135230557Sjimharris   switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
2136230557Sjimharris   {
2137230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
2138230557Sjimharris      scic_sds_request_set_status(
2139230557Sjimharris         this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
2140230557Sjimharris      );
2141230557Sjimharris      break;
2142230557Sjimharris
2143230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EARLY_RESP):
2144230557Sjimharris   {
2145230557Sjimharris      // There are times when the SCU hardware will return an early response
2146230557Sjimharris      // because the io request specified more data than is returned by the
2147230557Sjimharris      // target device (mode pages, inquiry data, etc.).  We must check the
2148230557Sjimharris      // response stats to see if this is truly a failed request or a good
2149230557Sjimharris      // request that just got completed early.
2150230557Sjimharris      SCI_SSP_RESPONSE_IU_T *response = (SCI_SSP_RESPONSE_IU_T *)
2151230557Sjimharris                                        this_request->response_buffer;
2152230557Sjimharris      scic_word_copy_with_swap(
2153230557Sjimharris         this_request->response_buffer,
2154230557Sjimharris         this_request->response_buffer,
2155230557Sjimharris         sizeof(SCI_SSP_RESPONSE_IU_T) / sizeof(U32)
2156230557Sjimharris      );
2157230557Sjimharris
2158230557Sjimharris      if (response->status == 0)
2159230557Sjimharris      {
2160230557Sjimharris         scic_sds_request_set_status(
2161230557Sjimharris            this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS_IO_DONE_EARLY
2162230557Sjimharris         );
2163230557Sjimharris      }
2164230557Sjimharris      else
2165230557Sjimharris      {
2166230557Sjimharris         scic_sds_request_set_status(
2167230557Sjimharris            this_request,
2168230557Sjimharris            SCU_TASK_DONE_CHECK_RESPONSE,
2169230557Sjimharris            SCI_FAILURE_IO_RESPONSE_VALID
2170230557Sjimharris         );
2171230557Sjimharris      }
2172230557Sjimharris   }
2173230557Sjimharris   break;
2174230557Sjimharris
2175230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CHECK_RESPONSE):
2176230557Sjimharris      scic_word_copy_with_swap(
2177230557Sjimharris         this_request->response_buffer,
2178230557Sjimharris         this_request->response_buffer,
2179230557Sjimharris         sizeof(SCI_SSP_RESPONSE_IU_T) / sizeof(U32)
2180230557Sjimharris      );
2181230557Sjimharris
2182230557Sjimharris      scic_sds_request_set_status(
2183230557Sjimharris         this_request,
2184230557Sjimharris         SCU_TASK_DONE_CHECK_RESPONSE,
2185230557Sjimharris         SCI_FAILURE_IO_RESPONSE_VALID
2186230557Sjimharris      );
2187230557Sjimharris      break;
2188230557Sjimharris
2189230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR):
2190230557Sjimharris      /// @todo With TASK_DONE_RESP_LEN_ERR is the response frame guaranteed
2191230557Sjimharris      ///       to be received before this completion status is posted?
2192230557Sjimharris      response_buffer =
2193230557Sjimharris         (SCI_SSP_RESPONSE_IU_T *)this_request->response_buffer;
2194230557Sjimharris      data_present =
2195230557Sjimharris         response_buffer->data_present & SCI_SSP_RESPONSE_IU_DATA_PRESENT_MASK;
2196230557Sjimharris
2197230557Sjimharris      if ((data_present == 0x01) || (data_present == 0x02))
2198230557Sjimharris      {
2199230557Sjimharris         scic_sds_request_set_status(
2200230557Sjimharris            this_request,
2201230557Sjimharris            SCU_TASK_DONE_CHECK_RESPONSE,
2202230557Sjimharris            SCI_FAILURE_IO_RESPONSE_VALID
2203230557Sjimharris         );
2204230557Sjimharris      }
2205230557Sjimharris      else
2206230557Sjimharris      {
2207230557Sjimharris         scic_sds_request_set_status(
2208230557Sjimharris            this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
2209230557Sjimharris         );
2210230557Sjimharris      }
2211230557Sjimharris      break;
2212230557Sjimharris
2213230557Sjimharris   //only stp device gets suspended.
2214230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
2215230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_PERR):
2216230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_ERR):
2217230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_DATA_LEN_ERR):
2218230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_ABORT_ERR):
2219230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_WD_LEN):
2220230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
2221230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_RESP):
2222230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_SDBFIS):
2223230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
2224230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDB_ERR):
2225230557Sjimharris      if (this_request->protocol == SCIC_STP_PROTOCOL)
2226230557Sjimharris      {
2227230557Sjimharris         SCIC_LOG_ERROR((
2228230557Sjimharris            sci_base_object_get_logger(this_request),
2229230557Sjimharris            SCIC_LOG_OBJECT_STP_IO_REQUEST,
2230230557Sjimharris            "SCIC IO Request 0x%x returning REMOTE_DEVICE_RESET_REQUIRED for completion code 0x%x\n",
2231230557Sjimharris            this_request, completion_code
2232230557Sjimharris         ));
2233230557Sjimharris         scic_sds_request_set_status(
2234230557Sjimharris            this_request,
2235230557Sjimharris            SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
2236230557Sjimharris            SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED
2237230557Sjimharris         );
2238230557Sjimharris      }
2239230557Sjimharris      else
2240230557Sjimharris      {
2241230557Sjimharris         SCIC_LOG_ERROR((
2242230557Sjimharris            sci_base_object_get_logger(this_request),
2243230557Sjimharris            SCIC_LOG_OBJECT_SSP_IO_REQUEST,
2244230557Sjimharris            "SCIC IO Request 0x%x returning CONTROLLER_SPECIFIC_IO_ERR for completion code 0x%x\n",
2245230557Sjimharris            this_request, completion_code
2246230557Sjimharris         ));
2247230557Sjimharris         scic_sds_request_set_status(
2248230557Sjimharris            this_request,
2249230557Sjimharris            SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
2250230557Sjimharris            SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2251230557Sjimharris         );
2252230557Sjimharris      }
2253230557Sjimharris      break;
2254230557Sjimharris
2255230557Sjimharris   //both stp/ssp device gets suspended
2256230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LF_ERR):
2257230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_WRONG_DESTINATION):
2258230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1):
2259230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2):
2260230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3):
2261230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_BAD_DESTINATION):
2262230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_ZONE_VIOLATION):
2263230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY):
2264230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED):
2265230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED):
2266230557Sjimharris      scic_sds_request_set_status(
2267230557Sjimharris         this_request,
2268230557Sjimharris         SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
2269230557Sjimharris         SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED
2270230557Sjimharris      );
2271230557Sjimharris     break;
2272230557Sjimharris
2273230557Sjimharris   //neither ssp nor stp gets suspended.
2274230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_CMD_ERR):
2275230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_XR):
2276230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_IU_LEN_ERR):
2277230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDMA_ERR):
2278230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OFFSET_ERR):
2279230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EXCESS_DATA):
2280230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR):
2281230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR):
2282230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR):
2283230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR):
2284230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_DATA):
2285230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OPEN_FAIL):
2286230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_VIIT_ENTRY_NV):
2287230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_IIT_ENTRY_NV):
2288230557Sjimharris   case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RNCNV_OUTBOUND):
2289230557Sjimharris   default:
2290230557Sjimharris      SCIC_LOG_ERROR((
2291230557Sjimharris         sci_base_object_get_logger(this_request),
2292230557Sjimharris         SCIC_LOG_OBJECT_SSP_IO_REQUEST | SCIC_LOG_OBJECT_STP_IO_REQUEST,
2293230557Sjimharris         "SCIC IO Request 0x%x returning CONTROLLER_SPECIFIC_IO_ERR for completion code 0x%x\n",
2294230557Sjimharris         this_request, completion_code
2295230557Sjimharris      ));
2296230557Sjimharris      scic_sds_request_set_status(
2297230557Sjimharris         this_request,
2298230557Sjimharris         SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
2299230557Sjimharris         SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2300230557Sjimharris      );
2301230557Sjimharris      break;
2302230557Sjimharris   }
2303230557Sjimharris
2304230557Sjimharris   /**
2305230557Sjimharris    * @todo This is probably wrong for ACK/NAK timeout conditions
2306230557Sjimharris    */
2307230557Sjimharris
2308230557Sjimharris   // In all cases we will treat this as the completion of the IO request.
2309230557Sjimharris   sci_base_state_machine_change_state(
2310230557Sjimharris      &this_request->parent.state_machine,
2311230557Sjimharris      SCI_BASE_REQUEST_STATE_COMPLETED
2312230557Sjimharris   );
2313230557Sjimharris
2314230557Sjimharris   return SCI_SUCCESS;
2315230557Sjimharris}
2316230557Sjimharris
2317230557Sjimharris/**
2318230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
2319230557Sjimharris * object receives a scic_sds_request_frame_handler() request.
2320230557Sjimharris *
2321230557Sjimharris * This method first determines the frame type received.  If this is a
2322230557Sjimharris * response frame then the response data is copied to the io request response
2323230557Sjimharris * buffer for processing at completion time.
2324230557Sjimharris *
2325230557Sjimharris * If the frame type is not a response buffer an error is logged.
2326230557Sjimharris *
2327230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
2328230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
2329230557Sjimharris *       requested.
2330230557Sjimharris * @param[in] frame_index This is the index of the unsolicited frame to be
2331230557Sjimharris *       processed.
2332230557Sjimharris *
2333230557Sjimharris * @return SCI_STATUS
2334230557Sjimharris * @retval SCI_SUCCESS
2335230557Sjimharris * @retval SCI_FAILURE_INVALID_PARAMETER_VALUE
2336230557Sjimharris */
2337230557Sjimharrisstatic
2338230557SjimharrisSCI_STATUS scic_sds_request_started_state_frame_handler(
2339230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
2340230557Sjimharris   U32                  frame_index
2341230557Sjimharris)
2342230557Sjimharris{
2343230557Sjimharris   SCI_STATUS status;
2344230557Sjimharris   SCI_SSP_FRAME_HEADER_T *frame_header;
2345230557Sjimharris
2346230557Sjimharris   /// @todo If this is a response frame we must record that we received it
2347230557Sjimharris   status = scic_sds_unsolicited_frame_control_get_header(
2348230557Sjimharris      &(scic_sds_request_get_controller(this_request)->uf_control),
2349230557Sjimharris      frame_index,
2350230557Sjimharris      (void**) &frame_header
2351230557Sjimharris   );
2352230557Sjimharris
2353230557Sjimharris   if (frame_header->frame_type == SCI_SAS_RESPONSE_FRAME)
2354230557Sjimharris   {
2355230557Sjimharris      SCI_SSP_RESPONSE_IU_T *response_buffer;
2356230557Sjimharris
2357230557Sjimharris      status = scic_sds_unsolicited_frame_control_get_buffer(
2358230557Sjimharris         &(scic_sds_request_get_controller(this_request)->uf_control),
2359230557Sjimharris         frame_index,
2360230557Sjimharris         (void**) &response_buffer
2361230557Sjimharris      );
2362230557Sjimharris
2363230557Sjimharris      scic_word_copy_with_swap(
2364230557Sjimharris         this_request->response_buffer,
2365230557Sjimharris         (U32 *)response_buffer,
2366230557Sjimharris         sizeof(SCI_SSP_RESPONSE_IU_T)
2367230557Sjimharris      );
2368230557Sjimharris
2369230557Sjimharris      response_buffer = (SCI_SSP_RESPONSE_IU_T *)this_request->response_buffer;
2370230557Sjimharris
2371230557Sjimharris      if (
2372230557Sjimharris            (response_buffer->data_present == 0x01)
2373230557Sjimharris         || (response_buffer->data_present == 0x02)
2374230557Sjimharris         )
2375230557Sjimharris      {
2376230557Sjimharris         scic_sds_request_set_status(
2377230557Sjimharris            this_request,
2378230557Sjimharris            SCU_TASK_DONE_CHECK_RESPONSE,
2379230557Sjimharris            SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
2380230557Sjimharris         );
2381230557Sjimharris      }
2382230557Sjimharris      else
2383230557Sjimharris      {
2384230557Sjimharris         scic_sds_request_set_status(
2385230557Sjimharris            this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
2386230557Sjimharris         );
2387230557Sjimharris      }
2388230557Sjimharris
2389230557Sjimharris   }
2390230557Sjimharris   else
2391230557Sjimharris   {
2392230557Sjimharris      // This was not a response frame why did it get forwarded?
2393230557Sjimharris      SCIC_LOG_ERROR((
2394230557Sjimharris         sci_base_object_get_logger(this_request),
2395230557Sjimharris         SCIC_LOG_OBJECT_SSP_IO_REQUEST,
2396230557Sjimharris         "SCIC IO Request 0x%x received unexpected frame %d type 0x%02x\n",
2397230557Sjimharris         this_request, frame_index, frame_header->frame_type
2398230557Sjimharris      ));
2399230557Sjimharris   }
2400230557Sjimharris
2401230557Sjimharris   // In any case we are done with this frame buffer return it to the
2402230557Sjimharris   // controller
2403230557Sjimharris   scic_sds_controller_release_frame(
2404230557Sjimharris      this_request->owning_controller, frame_index
2405230557Sjimharris   );
2406230557Sjimharris
2407230557Sjimharris   return SCI_SUCCESS;
2408230557Sjimharris}
2409230557Sjimharris
2410230557Sjimharris//*****************************************************************************
2411230557Sjimharris//*  COMPLETED STATE HANDLERS
2412230557Sjimharris//*****************************************************************************
2413230557Sjimharris
2414230557Sjimharris
2415230557Sjimharris/**
2416230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
2417230557Sjimharris * object receives a scic_sds_request_complete() request.
2418230557Sjimharris *
2419230557Sjimharris * This method frees up any io request resources that have been allocated and
2420230557Sjimharris * transitions the request to its final state.
2421230557Sjimharris *
2422230557Sjimharris * @todo Consider stopping the state machine instead of transitioning to the
2423230557Sjimharris *       final state?
2424230557Sjimharris *
2425230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
2426230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
2427230557Sjimharris *       requested.
2428230557Sjimharris *
2429230557Sjimharris * @return SCI_STATUS
2430230557Sjimharris * @retval SCI_SUCCESS
2431230557Sjimharris */
2432230557Sjimharrisstatic
2433230557SjimharrisSCI_STATUS scic_sds_request_completed_state_complete_handler(
2434230557Sjimharris   SCI_BASE_REQUEST_T *request
2435230557Sjimharris)
2436230557Sjimharris{
2437230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request;
2438230557Sjimharris
2439230557Sjimharris   if (this_request->was_tag_assigned_by_user != TRUE)
2440230557Sjimharris   {
2441230557Sjimharris      scic_controller_free_io_tag(
2442230557Sjimharris         this_request->owning_controller, this_request->io_tag
2443230557Sjimharris      );
2444230557Sjimharris   }
2445230557Sjimharris
2446230557Sjimharris   if (this_request->saved_rx_frame_index != SCU_INVALID_FRAME_INDEX)
2447230557Sjimharris   {
2448230557Sjimharris      scic_sds_controller_release_frame(
2449230557Sjimharris         this_request->owning_controller, this_request->saved_rx_frame_index);
2450230557Sjimharris   }
2451230557Sjimharris
2452230557Sjimharris   sci_base_state_machine_change_state(
2453230557Sjimharris      &this_request->parent.state_machine,
2454230557Sjimharris      SCI_BASE_REQUEST_STATE_FINAL
2455230557Sjimharris   );
2456230557Sjimharris
2457230557Sjimharris   scic_sds_request_deinitialize_state_logging(this_request);
2458230557Sjimharris
2459230557Sjimharris   return SCI_SUCCESS;
2460230557Sjimharris}
2461230557Sjimharris
2462230557Sjimharris//*****************************************************************************
2463230557Sjimharris//*  ABORTING STATE HANDLERS
2464230557Sjimharris//*****************************************************************************
2465230557Sjimharris
2466230557Sjimharris/**
2467230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
2468230557Sjimharris * object receives a scic_sds_request_terminate() request.
2469230557Sjimharris *
2470230557Sjimharris * This method is the io request aborting state abort handlers.  On receipt of
2471230557Sjimharris * a multiple terminate requests the io request will transition to the
2472230557Sjimharris * completed state.  This should not happen in normal operation.
2473230557Sjimharris *
2474230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
2475230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
2476230557Sjimharris *       requested.
2477230557Sjimharris *
2478230557Sjimharris * @return SCI_STATUS
2479230557Sjimharris * @retval SCI_SUCCESS
2480230557Sjimharris */
2481230557Sjimharrisstatic
2482230557SjimharrisSCI_STATUS scic_sds_request_aborting_state_abort_handler(
2483230557Sjimharris   SCI_BASE_REQUEST_T *request
2484230557Sjimharris)
2485230557Sjimharris{
2486230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request;
2487230557Sjimharris
2488230557Sjimharris   sci_base_state_machine_change_state(
2489230557Sjimharris      &this_request->parent.state_machine,
2490230557Sjimharris      SCI_BASE_REQUEST_STATE_COMPLETED
2491230557Sjimharris   );
2492230557Sjimharris
2493230557Sjimharris   return SCI_SUCCESS;
2494230557Sjimharris}
2495230557Sjimharris
2496230557Sjimharris/**
2497230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
2498230557Sjimharris * object receives a scic_sds_request_task_completion() request.
2499230557Sjimharris *
2500230557Sjimharris * This method decodes the completion type waiting for the abort task complete
2501230557Sjimharris * notification. When the abort task complete is received the io request
2502230557Sjimharris * transitions to the completed state.
2503230557Sjimharris *
2504230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
2505230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
2506230557Sjimharris *       requested.
2507230557Sjimharris *
2508230557Sjimharris * @return SCI_STATUS
2509230557Sjimharris * @retval SCI_SUCCESS
2510230557Sjimharris */
2511230557Sjimharrisstatic
2512230557SjimharrisSCI_STATUS scic_sds_request_aborting_state_tc_completion_handler(
2513230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
2514230557Sjimharris   U32                  completion_code
2515230557Sjimharris)
2516230557Sjimharris{
2517230557Sjimharris   SCIC_LOG_TRACE((
2518230557Sjimharris      sci_base_object_get_logger(this_request),
2519230557Sjimharris      SCIC_LOG_OBJECT_TASK_MANAGEMENT,
2520230557Sjimharris      "scic_sds_request_aborting_state_tc_completion_handler(0x%x,0x%x) enter\n",
2521230557Sjimharris      this_request, completion_code
2522230557Sjimharris   ));
2523230557Sjimharris
2524230557Sjimharris   switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
2525230557Sjimharris   {
2526230557Sjimharris   case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
2527230557Sjimharris   case (SCU_TASK_DONE_TASK_ABORT << SCU_COMPLETION_TL_STATUS_SHIFT):
2528230557Sjimharris      scic_sds_request_set_status(
2529230557Sjimharris         this_request, SCU_TASK_DONE_TASK_ABORT, SCI_FAILURE_IO_TERMINATED
2530230557Sjimharris      );
2531230557Sjimharris
2532230557Sjimharris      sci_base_state_machine_change_state(
2533230557Sjimharris         &this_request->parent.state_machine,
2534230557Sjimharris         SCI_BASE_REQUEST_STATE_COMPLETED
2535230557Sjimharris      );
2536230557Sjimharris      break;
2537230557Sjimharris
2538230557Sjimharris   default:
2539230557Sjimharris      // Unless we get some strange error wait for the task abort to complete
2540230557Sjimharris      // TODO: Should there be a state change for this completion?
2541230557Sjimharris      break;
2542230557Sjimharris   }
2543230557Sjimharris
2544230557Sjimharris   return SCI_SUCCESS;
2545230557Sjimharris}
2546230557Sjimharris
2547230557Sjimharris/**
2548230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
2549230557Sjimharris * object receives a scic_sds_request_frame_handler() request.
2550230557Sjimharris *
2551230557Sjimharris * This method discards the unsolicited frame since we are waiting for the
2552230557Sjimharris * abort task completion.
2553230557Sjimharris *
2554230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to
2555230557Sjimharris *       the SCIC_SDS_IO_REQUEST_T object for which the start operation is
2556230557Sjimharris *       requested.
2557230557Sjimharris *
2558230557Sjimharris * @return SCI_STATUS
2559230557Sjimharris * @retval SCI_SUCCESS
2560230557Sjimharris */
2561230557Sjimharrisstatic
2562230557SjimharrisSCI_STATUS scic_sds_request_aborting_state_frame_handler(
2563230557Sjimharris   SCIC_SDS_REQUEST_T * this_request,
2564230557Sjimharris   U32                  frame_index
2565230557Sjimharris)
2566230557Sjimharris{
2567230557Sjimharris   // TODO: Is it even possible to get an unsolicited frame in the aborting state?
2568230557Sjimharris
2569230557Sjimharris   scic_sds_controller_release_frame(
2570230557Sjimharris      this_request->owning_controller, frame_index);
2571230557Sjimharris
2572230557Sjimharris   return SCI_SUCCESS;
2573230557Sjimharris}
2574230557Sjimharris
2575230557Sjimharris// ---------------------------------------------------------------------------
2576230557Sjimharris
2577230557SjimharrisSCIC_SDS_IO_REQUEST_STATE_HANDLER_T
2578230557Sjimharris   scic_sds_request_state_handler_table[SCI_BASE_REQUEST_MAX_STATES] =
2579230557Sjimharris{
2580230557Sjimharris   // SCI_BASE_REQUEST_STATE_INITIAL
2581230557Sjimharris   {
2582230557Sjimharris      {
2583230557Sjimharris         scic_sds_request_default_start_handler,
2584230557Sjimharris         scic_sds_request_default_abort_handler,
2585230557Sjimharris         scic_sds_request_default_complete_handler,
2586230557Sjimharris         scic_sds_request_default_destruct_handler
2587230557Sjimharris      },
2588230557Sjimharris      scic_sds_request_default_tc_completion_handler,
2589230557Sjimharris      scic_sds_request_default_event_handler,
2590230557Sjimharris      scic_sds_request_default_frame_handler
2591230557Sjimharris   },
2592230557Sjimharris   // SCI_BASE_REQUEST_STATE_CONSTRUCTED
2593230557Sjimharris   {
2594230557Sjimharris      {
2595230557Sjimharris         scic_sds_request_constructed_state_start_handler,
2596230557Sjimharris         scic_sds_request_constructed_state_abort_handler,
2597230557Sjimharris         scic_sds_request_default_complete_handler,
2598230557Sjimharris         scic_sds_request_default_destruct_handler
2599230557Sjimharris      },
2600230557Sjimharris      scic_sds_request_default_tc_completion_handler,
2601230557Sjimharris      scic_sds_request_default_event_handler,
2602230557Sjimharris      scic_sds_request_default_frame_handler
2603230557Sjimharris   },
2604230557Sjimharris   // SCI_BASE_REQUEST_STATE_STARTED
2605230557Sjimharris   {
2606230557Sjimharris      {
2607230557Sjimharris         scic_sds_request_default_start_handler,
2608230557Sjimharris         scic_sds_request_started_state_abort_handler,
2609230557Sjimharris         scic_sds_request_default_complete_handler,
2610230557Sjimharris         scic_sds_request_default_destruct_handler
2611230557Sjimharris      },
2612230557Sjimharris      scic_sds_request_started_state_tc_completion_handler,
2613230557Sjimharris      scic_sds_request_default_event_handler,
2614230557Sjimharris      scic_sds_request_started_state_frame_handler
2615230557Sjimharris   },
2616230557Sjimharris   // SCI_BASE_REQUEST_STATE_COMPLETED
2617230557Sjimharris   {
2618230557Sjimharris      {
2619230557Sjimharris         scic_sds_request_default_start_handler,
2620230557Sjimharris         scic_sds_request_default_abort_handler,
2621230557Sjimharris         scic_sds_request_completed_state_complete_handler,
2622230557Sjimharris         scic_sds_request_default_destruct_handler
2623230557Sjimharris      },
2624230557Sjimharris      scic_sds_request_default_tc_completion_handler,
2625230557Sjimharris      scic_sds_request_default_event_handler,
2626230557Sjimharris      scic_sds_request_default_frame_handler
2627230557Sjimharris   },
2628230557Sjimharris   // SCI_BASE_REQUEST_STATE_ABORTING
2629230557Sjimharris   {
2630230557Sjimharris      {
2631230557Sjimharris         scic_sds_request_default_start_handler,
2632230557Sjimharris         scic_sds_request_aborting_state_abort_handler,
2633230557Sjimharris         scic_sds_request_default_complete_handler,
2634230557Sjimharris         scic_sds_request_default_destruct_handler
2635230557Sjimharris      },
2636230557Sjimharris      scic_sds_request_aborting_state_tc_completion_handler,
2637230557Sjimharris      scic_sds_request_default_event_handler,
2638230557Sjimharris      scic_sds_request_aborting_state_frame_handler,
2639230557Sjimharris   },
2640230557Sjimharris   // SCI_BASE_REQUEST_STATE_FINAL
2641230557Sjimharris   {
2642230557Sjimharris      {
2643230557Sjimharris         scic_sds_request_default_start_handler,
2644230557Sjimharris         scic_sds_request_default_abort_handler,
2645230557Sjimharris         scic_sds_request_default_complete_handler,
2646230557Sjimharris         scic_sds_request_default_destruct_handler
2647230557Sjimharris      },
2648230557Sjimharris      scic_sds_request_default_tc_completion_handler,
2649230557Sjimharris      scic_sds_request_default_event_handler,
2650230557Sjimharris      scic_sds_request_default_frame_handler
2651230557Sjimharris   }
2652230557Sjimharris};
2653230557Sjimharris
2654230557Sjimharris/**
2655230557Sjimharris * This method implements the actions taken when entering the
2656230557Sjimharris * SCI_BASE_REQUEST_STATE_INITIAL state. This state is entered when the
2657230557Sjimharris * initial base request is constructed. Entry into the initial state sets all
2658230557Sjimharris * handlers for the io request object to their default handlers.
2659230557Sjimharris *
2660230557Sjimharris * @param[in] object This parameter specifies the base object for which the
2661230557Sjimharris *       state transition is occurring.
2662230557Sjimharris *
2663230557Sjimharris * @return none
2664230557Sjimharris */
2665230557Sjimharrisstatic
2666230557Sjimharrisvoid scic_sds_request_initial_state_enter(
2667230557Sjimharris   SCI_BASE_OBJECT_T *object
2668230557Sjimharris)
2669230557Sjimharris{
2670230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2671230557Sjimharris
2672230557Sjimharris   SET_STATE_HANDLER(
2673230557Sjimharris      this_request,
2674230557Sjimharris      scic_sds_request_state_handler_table,
2675230557Sjimharris      SCI_BASE_REQUEST_STATE_INITIAL
2676230557Sjimharris   );
2677230557Sjimharris}
2678230557Sjimharris
2679230557Sjimharris/**
2680230557Sjimharris * This method implements the actions taken when entering the
2681230557Sjimharris * SCI_BASE_REQUEST_STATE_CONSTRUCTED state.
2682240518Seadler * The method sets the state handlers for the constructed state.
2683230557Sjimharris *
2684230557Sjimharris * @param[in] object The io request object that is to enter the constructed
2685230557Sjimharris *       state.
2686230557Sjimharris *
2687230557Sjimharris * @return none
2688230557Sjimharris */
2689230557Sjimharrisstatic
2690230557Sjimharrisvoid scic_sds_request_constructed_state_enter(
2691230557Sjimharris   SCI_BASE_OBJECT_T *object
2692230557Sjimharris)
2693230557Sjimharris{
2694230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2695230557Sjimharris
2696230557Sjimharris   SET_STATE_HANDLER(
2697230557Sjimharris      this_request,
2698230557Sjimharris      scic_sds_request_state_handler_table,
2699230557Sjimharris      SCI_BASE_REQUEST_STATE_CONSTRUCTED
2700230557Sjimharris   );
2701230557Sjimharris}
2702230557Sjimharris
2703230557Sjimharris/**
2704230557Sjimharris * This method implements the actions taken when entering the
2705230557Sjimharris * SCI_BASE_REQUEST_STATE_STARTED state. If the io request object type is a
2706230557Sjimharris * SCSI Task request we must enter the started substate machine.
2707230557Sjimharris *
2708230557Sjimharris * @param[in] object This parameter specifies the base object for which the
2709230557Sjimharris *       state transition is occuring.  This is cast into a
2710230557Sjimharris *       SCIC_SDS_IO_REQUEST object.
2711230557Sjimharris *
2712230557Sjimharris * @return none
2713230557Sjimharris */
2714230557Sjimharrisstatic
2715230557Sjimharrisvoid scic_sds_request_started_state_enter(
2716230557Sjimharris   SCI_BASE_OBJECT_T *object
2717230557Sjimharris)
2718230557Sjimharris{
2719230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2720230557Sjimharris
2721230557Sjimharris   SET_STATE_HANDLER(
2722230557Sjimharris      this_request,
2723230557Sjimharris      scic_sds_request_state_handler_table,
2724230557Sjimharris      SCI_BASE_REQUEST_STATE_STARTED
2725230557Sjimharris   );
2726230557Sjimharris
2727230557Sjimharris   // Most of the request state machines have a started substate machine so
2728230557Sjimharris   // start its execution on the entry to the started state.
2729230557Sjimharris   if (this_request->has_started_substate_machine == TRUE)
2730230557Sjimharris      sci_base_state_machine_start(&this_request->started_substate_machine);
2731230557Sjimharris}
2732230557Sjimharris
2733230557Sjimharris/**
2734230557Sjimharris * This method implements the actions taken when exiting the
2735230557Sjimharris * SCI_BASE_REQUEST_STATE_STARTED state. For task requests the action will be
2736230557Sjimharris * to stop the started substate machine.
2737230557Sjimharris *
2738230557Sjimharris * @param[in] object This parameter specifies the base object for which the
2739230557Sjimharris *       state transition is occuring.  This object is cast into a
2740230557Sjimharris *       SCIC_SDS_IO_REQUEST object.
2741230557Sjimharris *
2742230557Sjimharris * @return none
2743230557Sjimharris */
2744230557Sjimharrisstatic
2745230557Sjimharrisvoid scic_sds_request_started_state_exit(
2746230557Sjimharris   SCI_BASE_OBJECT_T *object
2747230557Sjimharris)
2748230557Sjimharris{
2749230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2750230557Sjimharris
2751230557Sjimharris   if (this_request->has_started_substate_machine == TRUE)
2752230557Sjimharris      sci_base_state_machine_stop(&this_request->started_substate_machine);
2753230557Sjimharris}
2754230557Sjimharris
2755230557Sjimharris/**
2756230557Sjimharris * This method implements the actions taken when entering the
2757230557Sjimharris * SCI_BASE_REQUEST_STATE_COMPLETED state.  This state is entered when the
2758230557Sjimharris * SCIC_SDS_IO_REQUEST has completed.  The method will decode the request
2759230557Sjimharris * completion status and convert it to an SCI_STATUS to return in the
2760230557Sjimharris * completion callback function.
2761230557Sjimharris *
2762230557Sjimharris * @param[in] object This parameter specifies the base object for which the
2763230557Sjimharris *       state transition is occuring.  This object is cast into a
2764230557Sjimharris *       SCIC_SDS_IO_REQUEST object.
2765230557Sjimharris *
2766230557Sjimharris * @return none
2767230557Sjimharris */
2768230557Sjimharrisstatic
2769230557Sjimharrisvoid scic_sds_request_completed_state_enter(
2770230557Sjimharris   SCI_BASE_OBJECT_T *object
2771230557Sjimharris)
2772230557Sjimharris{
2773230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2774230557Sjimharris
2775230557Sjimharris   SET_STATE_HANDLER(
2776230557Sjimharris      this_request,
2777230557Sjimharris      scic_sds_request_state_handler_table,
2778230557Sjimharris      SCI_BASE_REQUEST_STATE_COMPLETED
2779230557Sjimharris   );
2780230557Sjimharris
2781230557Sjimharris   // Tell the SCI_USER that the IO request is complete
2782230557Sjimharris   if (this_request->is_task_management_request == FALSE)
2783230557Sjimharris   {
2784230557Sjimharris      scic_cb_io_request_complete(
2785230557Sjimharris         scic_sds_request_get_controller(this_request),
2786230557Sjimharris         scic_sds_request_get_device(this_request),
2787230557Sjimharris         this_request,
2788230557Sjimharris         this_request->sci_status
2789230557Sjimharris      );
2790230557Sjimharris   }
2791230557Sjimharris   else
2792230557Sjimharris   {
2793230557Sjimharris      scic_cb_task_request_complete(
2794230557Sjimharris         scic_sds_request_get_controller(this_request),
2795230557Sjimharris         scic_sds_request_get_device(this_request),
2796230557Sjimharris         this_request,
2797230557Sjimharris         this_request->sci_status
2798230557Sjimharris      );
2799230557Sjimharris   }
2800230557Sjimharris}
2801230557Sjimharris
2802230557Sjimharris/**
2803230557Sjimharris * This method implements the actions taken when entering the
2804230557Sjimharris * SCI_BASE_REQUEST_STATE_ABORTING state.
2805230557Sjimharris *
2806230557Sjimharris * @param[in] object This parameter specifies the base object for which the
2807230557Sjimharris *       state transition is occuring.  This object is cast into a
2808230557Sjimharris *       SCIC_SDS_IO_REQUEST object.
2809230557Sjimharris *
2810230557Sjimharris * @return none
2811230557Sjimharris */
2812230557Sjimharrisstatic
2813230557Sjimharrisvoid scic_sds_request_aborting_state_enter(
2814230557Sjimharris   SCI_BASE_OBJECT_T *object
2815230557Sjimharris)
2816230557Sjimharris{
2817230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2818230557Sjimharris
2819230557Sjimharris   // Setting the abort bit in the Task Context is required by the silicon.
2820230557Sjimharris   this_request->task_context_buffer->abort = 1;
2821230557Sjimharris
2822230557Sjimharris   SET_STATE_HANDLER(
2823230557Sjimharris      this_request,
2824230557Sjimharris      scic_sds_request_state_handler_table,
2825230557Sjimharris      SCI_BASE_REQUEST_STATE_ABORTING
2826230557Sjimharris   );
2827230557Sjimharris}
2828230557Sjimharris
2829230557Sjimharris/**
2830230557Sjimharris * This method implements the actions taken when entering the
2831230557Sjimharris * SCI_BASE_REQUEST_STATE_FINAL state. The only action required is to put the
2832230557Sjimharris * state handlers in place.
2833230557Sjimharris *
2834230557Sjimharris * @param[in] object This parameter specifies the base object for which the
2835230557Sjimharris *       state transition is occuring.  This is cast into a
2836230557Sjimharris *       SCIC_SDS_IO_REQUEST object.
2837230557Sjimharris *
2838230557Sjimharris * @return none
2839230557Sjimharris */
2840230557Sjimharrisstatic
2841230557Sjimharrisvoid scic_sds_request_final_state_enter(
2842230557Sjimharris   SCI_BASE_OBJECT_T *object
2843230557Sjimharris)
2844230557Sjimharris{
2845230557Sjimharris   SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
2846230557Sjimharris
2847230557Sjimharris   SET_STATE_HANDLER(
2848230557Sjimharris      this_request,
2849230557Sjimharris      scic_sds_request_state_handler_table,
2850230557Sjimharris      SCI_BASE_REQUEST_STATE_FINAL
2851230557Sjimharris   );
2852230557Sjimharris}
2853230557Sjimharris
2854230557Sjimharris// ---------------------------------------------------------------------------
2855230557Sjimharris
2856230557SjimharrisSCI_BASE_STATE_T
2857230557Sjimharris   scic_sds_request_state_table[SCI_BASE_REQUEST_MAX_STATES] =
2858230557Sjimharris{
2859230557Sjimharris   {
2860230557Sjimharris      SCI_BASE_REQUEST_STATE_INITIAL,
2861230557Sjimharris      scic_sds_request_initial_state_enter,
2862230557Sjimharris      NULL
2863230557Sjimharris   },
2864230557Sjimharris   {
2865230557Sjimharris      SCI_BASE_REQUEST_STATE_CONSTRUCTED,
2866230557Sjimharris      scic_sds_request_constructed_state_enter,
2867230557Sjimharris      NULL
2868230557Sjimharris   },
2869230557Sjimharris   {
2870230557Sjimharris      SCI_BASE_REQUEST_STATE_STARTED,
2871230557Sjimharris      scic_sds_request_started_state_enter,
2872230557Sjimharris      scic_sds_request_started_state_exit
2873230557Sjimharris   },
2874230557Sjimharris   {
2875230557Sjimharris      SCI_BASE_REQUEST_STATE_COMPLETED,
2876230557Sjimharris      scic_sds_request_completed_state_enter,
2877230557Sjimharris      NULL
2878230557Sjimharris   },
2879230557Sjimharris   {
2880230557Sjimharris      SCI_BASE_REQUEST_STATE_ABORTING,
2881230557Sjimharris      scic_sds_request_aborting_state_enter,
2882230557Sjimharris      NULL
2883230557Sjimharris   },
2884230557Sjimharris   {
2885230557Sjimharris      SCI_BASE_REQUEST_STATE_FINAL,
2886230557Sjimharris      scic_sds_request_final_state_enter,
2887230557Sjimharris      NULL
2888230557Sjimharris   }
2889230557Sjimharris};
2890230557Sjimharris
2891