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 structures, constants, and prototypes
60230557Sjimharris*        associated with the remote node context in the silicon.  It
61230557Sjimharris*        exists to model and manage the remote node context in the silicon.
62230557Sjimharris*/
63230557Sjimharris
64230557Sjimharris#include <dev/isci/scil/sci_util.h>
65230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h>
66230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h>
67230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h>
68230557Sjimharris#include <dev/isci/scil/scic_sds_remote_node_context.h>
69230557Sjimharris#include <dev/isci/scil/sci_base_state_machine.h>
70230557Sjimharris#include <dev/isci/scil/scic_remote_device.h>
71230557Sjimharris#include <dev/isci/scil/scic_sds_port.h>
72230557Sjimharris#include <dev/isci/scil/scu_event_codes.h>
73230557Sjimharris#include <dev/isci/scil/scu_task_context.h>
74230557Sjimharris
75230557Sjimharris/**
76230557Sjimharris* @brief
77230557Sjimharris*/
78230557Sjimharris   void scic_sds_remote_node_context_construct(
79230557Sjimharris   SCIC_SDS_REMOTE_DEVICE_T       * device,
80230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc,
81230557Sjimharris   U16                              remote_node_index
82230557Sjimharris      )
83230557Sjimharris{
84230557Sjimharris   memset (rnc, 0, sizeof(SCIC_SDS_REMOTE_NODE_CONTEXT_T) );
85230557Sjimharris
86230557Sjimharris   rnc->remote_node_index = remote_node_index;
87230557Sjimharris   rnc->device            = device;
88230557Sjimharris   rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
89230557Sjimharris
90230557Sjimharris   rnc->parent.logger = device->parent.parent.logger;
91230557Sjimharris
92230557Sjimharris   sci_base_state_machine_construct(
93230557Sjimharris      &rnc->state_machine,
94230557Sjimharris      &rnc->parent,
95230557Sjimharris      scic_sds_remote_node_context_state_table,
96230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE
97230557Sjimharris         );
98230557Sjimharris
99230557Sjimharris   sci_base_state_machine_start(&rnc->state_machine);
100230557Sjimharris
101230557Sjimharris   // State logging initialization takes place late for the remote node context
102230557Sjimharris   // see the resume state handler for the initial state.
103230557Sjimharris}
104230557Sjimharris
105230557Sjimharris/**
106230557Sjimharris* This method will return TRUE if the RNC is not in the initial state.  In
107230557Sjimharris* all other states the RNC is considered active and this will return TRUE.
108230557Sjimharris*
109230557Sjimharris* @note The destroy request of the state machine drives the RNC back to the
110230557Sjimharris*       initial state.  If the state machine changes then this routine will
111230557Sjimharris*       also have to be changed.
112230557Sjimharris*
113230557Sjimharris* @param[in] this_rnc The RNC for which the is posted request is being made.
114230557Sjimharris*
115230557Sjimharris* @return BOOL
116230557Sjimharris* @retval TRUE if the state machine is not in the initial state
117230557Sjimharris* @retval FALSE if the state machine is in the initial state
118230557Sjimharris*/
119230557Sjimharris   BOOL scic_sds_remote_node_context_is_initialized(
120230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
121230557Sjimharris      )
122230557Sjimharris{
123230557Sjimharris   U32 current_state = sci_base_state_machine_get_state(&this_rnc->state_machine);
124230557Sjimharris
125230557Sjimharris   if (current_state == SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE)
126230557Sjimharris   {
127230557Sjimharris      return FALSE;
128230557Sjimharris   }
129230557Sjimharris
130230557Sjimharris   return TRUE;
131230557Sjimharris}
132230557Sjimharris
133230557Sjimharris/**
134230557Sjimharris* This method will return TRUE if the remote node context is in a READY state
135230557Sjimharris* otherwise it will return FALSE
136230557Sjimharris*
137230557Sjimharris* @param[in] this_rnc The state of the remote node context object to check.
138230557Sjimharris*
139230557Sjimharris* @return BOOL
140230557Sjimharris* @retval TRUE if the remote node context is in the ready state.
141230557Sjimharris* @retval FALSE if the remote node context is not in the ready state.
142230557Sjimharris*/
143230557Sjimharris   BOOL scic_sds_remote_node_context_is_ready(
144230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
145230557Sjimharris      )
146230557Sjimharris{
147230557Sjimharris   U32 current_state = sci_base_state_machine_get_state(&this_rnc->state_machine);
148230557Sjimharris
149230557Sjimharris   if (current_state == SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE)
150230557Sjimharris   {
151230557Sjimharris      return TRUE;
152230557Sjimharris   }
153230557Sjimharris
154230557Sjimharris   return FALSE;
155230557Sjimharris}
156230557Sjimharris
157230557Sjimharris/**
158230557Sjimharris* This method will construct the RNC buffer for this remote device object.
159230557Sjimharris*
160230557Sjimharris* @param[in] this_device The remote device to use to construct the RNC
161230557Sjimharris*       buffer.
162230557Sjimharris* @param[in] rnc The buffer into which the remote device data will be copied.
163230557Sjimharris*
164230557Sjimharris* @return none
165230557Sjimharris*/
166230557Sjimharris   void scic_sds_remote_node_context_construct_buffer(
167230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
168230557Sjimharris      )
169230557Sjimharris{
170230557Sjimharris   SCU_REMOTE_NODE_CONTEXT_T * rnc;
171230557Sjimharris   SCIC_SDS_CONTROLLER_T     * the_controller;
172230557Sjimharris
173230557Sjimharris   the_controller = scic_sds_remote_device_get_controller(this_rnc->device);
174230557Sjimharris
175230557Sjimharris   rnc = scic_sds_controller_get_remote_node_context_buffer(
176230557Sjimharris      the_controller, this_rnc->remote_node_index);
177230557Sjimharris
178230557Sjimharris   memset(
179230557Sjimharris      rnc,
180230557Sjimharris      0x00,
181230557Sjimharris      sizeof(SCU_REMOTE_NODE_CONTEXT_T)
182230557Sjimharris         * scic_sds_remote_device_node_count(this_rnc->device)
183230557Sjimharris         );
184230557Sjimharris
185230557Sjimharris   rnc->ssp.remote_node_index = this_rnc->remote_node_index;
186230557Sjimharris   rnc->ssp.remote_node_port_width = this_rnc->device->device_port_width;
187230557Sjimharris   rnc->ssp.logical_port_index =
188230557Sjimharris      scic_sds_remote_device_get_port_index(this_rnc->device);
189230557Sjimharris
190230557Sjimharris   rnc->ssp.remote_sas_address_hi = SCIC_SWAP_DWORD(this_rnc->device->device_address.high);
191230557Sjimharris   rnc->ssp.remote_sas_address_lo = SCIC_SWAP_DWORD(this_rnc->device->device_address.low);
192230557Sjimharris
193230557Sjimharris   rnc->ssp.nexus_loss_timer_enable = TRUE;
194230557Sjimharris   rnc->ssp.check_bit               = FALSE;
195230557Sjimharris   rnc->ssp.is_valid                = FALSE;
196230557Sjimharris   rnc->ssp.is_remote_node_context  = TRUE;
197230557Sjimharris   rnc->ssp.function_number         = 0;
198230557Sjimharris
199230557Sjimharris   rnc->ssp.arbitration_wait_time = 0;
200230557Sjimharris
201230557Sjimharris
202230557Sjimharris   if (
203230557Sjimharris      this_rnc->device->target_protocols.u.bits.attached_sata_device
204230557Sjimharris         || this_rnc->device->target_protocols.u.bits.attached_stp_target
205230557Sjimharris         )
206230557Sjimharris   {
207230557Sjimharris      rnc->ssp.connection_occupancy_timeout =
208230557Sjimharris         the_controller->user_parameters.sds1.stp_max_occupancy_timeout;
209230557Sjimharris      rnc->ssp.connection_inactivity_timeout =
210230557Sjimharris         the_controller->user_parameters.sds1.stp_inactivity_timeout;
211230557Sjimharris   }
212230557Sjimharris   else
213230557Sjimharris   {
214230557Sjimharris      rnc->ssp.connection_occupancy_timeout  =
215230557Sjimharris         the_controller->user_parameters.sds1.ssp_max_occupancy_timeout;
216230557Sjimharris      rnc->ssp.connection_inactivity_timeout =
217230557Sjimharris         the_controller->user_parameters.sds1.ssp_inactivity_timeout;
218230557Sjimharris   }
219230557Sjimharris
220230557Sjimharris   rnc->ssp.initial_arbitration_wait_time = 0;
221230557Sjimharris
222230557Sjimharris   // Open Address Frame Parameters
223230557Sjimharris   rnc->ssp.oaf_connection_rate = this_rnc->device->connection_rate;
224230557Sjimharris   rnc->ssp.oaf_features = 0;
225230557Sjimharris   rnc->ssp.oaf_source_zone_group = 0;
226230557Sjimharris   rnc->ssp.oaf_more_compatibility_features = 0;
227230557Sjimharris}
228230557Sjimharris
229230557Sjimharris// ---------------------------------------------------------------------------
230230557Sjimharris
231230557Sjimharris#ifdef SCI_LOGGING
232230557Sjimharris/**
233230557Sjimharris* This method will enable and turn on state transition logging for the remote
234230557Sjimharris* node context object.
235230557Sjimharris*
236230557Sjimharris* @param[in] this_rnc The remote node context for which state transition
237230557Sjimharris*       logging is to be enabled.
238230557Sjimharris*
239230557Sjimharris* @return none
240230557Sjimharris*/
241230557Sjimharris   void scic_sds_remote_node_context_initialize_state_logging(
242230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
243230557Sjimharris      )
244230557Sjimharris{
245230557Sjimharris   sci_base_state_machine_logger_initialize(
246230557Sjimharris      &this_rnc->state_machine_logger,
247230557Sjimharris      &this_rnc->state_machine,
248230557Sjimharris      &this_rnc->parent,
249230557Sjimharris      scic_cb_logger_log_states,
250230557Sjimharris      "SCIC_SDS_REMOTE_NODE_CONTEXT_T", "state machine",
251230557Sjimharris      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
252230557Sjimharris         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
253230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET
254230557Sjimharris         );
255230557Sjimharris}
256230557Sjimharris
257230557Sjimharris/**
258230557Sjimharris* This method will stop the state machine logging for this object and should
259230557Sjimharris* be called before the object is destroyed.
260230557Sjimharris*
261230557Sjimharris* @param[in] this_rnc The remote node context on which to stop logging state
262230557Sjimharris*       transitions.
263230557Sjimharris*
264230557Sjimharris* @return none
265230557Sjimharris*/
266230557Sjimharris   void scic_sds_remote_node_context_deinitialize_state_logging(
267230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
268230557Sjimharris      )
269230557Sjimharris{
270230557Sjimharris   sci_base_state_machine_logger_deinitialize(
271230557Sjimharris      &this_rnc->state_machine_logger,
272230557Sjimharris      &this_rnc->state_machine
273230557Sjimharris         );
274230557Sjimharris}
275230557Sjimharris#endif
276230557Sjimharris
277230557Sjimharris/**
278230557Sjimharris* This method will setup the remote node context object so it will transition
279230557Sjimharris* to its ready state.  If the remote node context is already setup to
280230557Sjimharris* transition to its final state then this function does nothing.
281230557Sjimharris*
282230557Sjimharris* @param[in] this_rnc
283230557Sjimharris* @param[in] the_callback
284230557Sjimharris* @param[in] callback_parameter
285230557Sjimharris*
286230557Sjimharris* @return none
287230557Sjimharris*/
288230557Sjimharrisstatic
289230557Sjimharrisvoid scic_sds_remote_node_context_setup_to_resume(
290230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
291230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
292230557Sjimharris   void                                   * callback_parameter
293230557Sjimharris)
294230557Sjimharris{
295230557Sjimharris   if (this_rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL)
296230557Sjimharris   {
297230557Sjimharris      this_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY;
298230557Sjimharris      this_rnc->user_callback     = the_callback;
299230557Sjimharris      this_rnc->user_cookie       = callback_parameter;
300230557Sjimharris   }
301230557Sjimharris}
302230557Sjimharris
303230557Sjimharris/**
304230557Sjimharris* This method will setup the remote node context object so it will
305230557Sjimharris* transistion to its final state.
306230557Sjimharris*
307230557Sjimharris* @param[in] this_rnc
308230557Sjimharris* @param[in] the_callback
309230557Sjimharris* @param[in] callback_parameter
310230557Sjimharris*
311230557Sjimharris* @return none
312230557Sjimharris*/
313230557Sjimharrisstatic
314230557Sjimharrisvoid scic_sds_remote_node_context_setup_to_destory(
315230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
316230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
317230557Sjimharris   void                                   * callback_parameter
318230557Sjimharris)
319230557Sjimharris{
320230557Sjimharris   this_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL;
321230557Sjimharris   this_rnc->user_callback     = the_callback;
322230557Sjimharris   this_rnc->user_cookie       = callback_parameter;
323230557Sjimharris}
324230557Sjimharris
325230557Sjimharris/**
326230557Sjimharris* This method will continue to resume a remote node context.  This is used
327230557Sjimharris* in the states where a resume is requested while a resume is in progress.
328230557Sjimharris*
329230557Sjimharris* @param[in] this_rnc
330230557Sjimharris* @param[in] the_callback
331230557Sjimharris* @param[in] callback_parameter
332230557Sjimharris*/
333230557Sjimharrisstatic
334230557SjimharrisSCI_STATUS scic_sds_remote_node_context_continue_to_resume_handler(
335230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
336230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
337230557Sjimharris   void                                   * callback_parameter
338230557Sjimharris)
339230557Sjimharris{
340230557Sjimharris   if (this_rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY)
341230557Sjimharris   {
342230557Sjimharris      this_rnc->user_callback = the_callback;
343230557Sjimharris      this_rnc->user_cookie   = callback_parameter;
344230557Sjimharris
345230557Sjimharris      return SCI_SUCCESS;
346230557Sjimharris   }
347230557Sjimharris
348230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
349230557Sjimharris}
350230557Sjimharris
351230557Sjimharris//******************************************************************************
352230557Sjimharris//* REMOTE NODE CONTEXT STATE MACHINE
353230557Sjimharris//******************************************************************************
354230557Sjimharris
355230557Sjimharrisstatic
356230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_destruct_handler(
357230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
358230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
359230557Sjimharris   void                                   * callback_parameter
360230557Sjimharris)
361230557Sjimharris{
362230557Sjimharris   SCIC_LOG_WARNING((
363230557Sjimharris      sci_base_object_get_logger(this_rnc->device),
364230557Sjimharris      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
365230557Sjimharris         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
366230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
367230557Sjimharris      "SCIC Remote Node Context 0x%x requested to stop while in unexpected state %d\n",
368230557Sjimharris      this_rnc, sci_base_state_machine_get_state(&this_rnc->state_machine)
369230557Sjimharris         ));
370230557Sjimharris
371230557Sjimharris   // We have decided that the destruct request on the remote node context can not fail
372230557Sjimharris   // since it is either in the initial/destroyed state or is can be destroyed.
373230557Sjimharris   return SCI_SUCCESS;
374230557Sjimharris}
375230557Sjimharris
376230557Sjimharrisstatic
377230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_suspend_handler(
378230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
379230557Sjimharris   U32                                      suspend_type,
380230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
381230557Sjimharris   void                                   * callback_parameter
382230557Sjimharris)
383230557Sjimharris{
384230557Sjimharris   SCIC_LOG_WARNING((
385230557Sjimharris      sci_base_object_get_logger(this_rnc->device),
386230557Sjimharris      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
387230557Sjimharris         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
388230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
389230557Sjimharris      "SCIC Remote Node Context 0x%x requested to suspend while in wrong state %d\n",
390230557Sjimharris      this_rnc, sci_base_state_machine_get_state(&this_rnc->state_machine)
391230557Sjimharris         ));
392230557Sjimharris
393230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
394230557Sjimharris}
395230557Sjimharris
396230557Sjimharrisstatic
397230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_resume_handler(
398230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
399230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
400230557Sjimharris   void                                   * callback_parameter
401230557Sjimharris)
402230557Sjimharris{
403230557Sjimharris   SCIC_LOG_WARNING((
404230557Sjimharris      sci_base_object_get_logger(this_rnc->device),
405230557Sjimharris      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
406230557Sjimharris         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
407230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
408230557Sjimharris      "SCIC Remote Node Context 0x%x requested to resume while in wrong state %d\n",
409230557Sjimharris      this_rnc, sci_base_state_machine_get_state(&this_rnc->state_machine)
410230557Sjimharris         ));
411230557Sjimharris
412230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
413230557Sjimharris}
414230557Sjimharris
415230557Sjimharrisstatic
416230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_start_io_handler(
417230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
418230557Sjimharris   struct SCIC_SDS_REQUEST             * the_request
419230557Sjimharris)
420230557Sjimharris{
421230557Sjimharris   SCIC_LOG_WARNING((
422230557Sjimharris      sci_base_object_get_logger(this_rnc->device),
423230557Sjimharris      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
424230557Sjimharris         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
425230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
426230557Sjimharris      "SCIC Remote Node Context 0x%x requested to start io 0x%x while in wrong state %d\n",
427230557Sjimharris      this_rnc, the_request, sci_base_state_machine_get_state(&this_rnc->state_machine)
428230557Sjimharris         ));
429230557Sjimharris
430230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
431230557Sjimharris}
432230557Sjimharris
433230557Sjimharrisstatic
434230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_start_task_handler(
435230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
436230557Sjimharris   struct SCIC_SDS_REQUEST             * the_request
437230557Sjimharris)
438230557Sjimharris{
439230557Sjimharris   SCIC_LOG_WARNING((
440230557Sjimharris      sci_base_object_get_logger(this_rnc->device),
441230557Sjimharris      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
442230557Sjimharris         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
443230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
444230557Sjimharris      "SCIC Remote Node Context 0x%x requested to start task 0x%x while in wrong state %d\n",
445230557Sjimharris      this_rnc, the_request, sci_base_state_machine_get_state(&this_rnc->state_machine)
446230557Sjimharris         ));
447230557Sjimharris
448230557Sjimharris   return SCI_FAILURE;
449230557Sjimharris}
450230557Sjimharris
451230557Sjimharrisstatic
452230557SjimharrisSCI_STATUS scic_sds_remote_node_context_default_event_handler(
453230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
454230557Sjimharris   U32                                   event_code
455230557Sjimharris)
456230557Sjimharris{
457230557Sjimharris   SCIC_LOG_WARNING((
458230557Sjimharris      sci_base_object_get_logger(this_rnc->device),
459230557Sjimharris      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
460230557Sjimharris         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
461230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
462230557Sjimharris      "SCIC Remote Node Context 0x%x requested to process event 0x%x while in wrong state %d\n",
463230557Sjimharris      this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine)
464230557Sjimharris         ));
465230557Sjimharris
466230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
467230557Sjimharris}
468230557Sjimharris
469230557Sjimharris/**
470230557Sjimharris* This method determines if the task request can be started by the SCU
471230557Sjimharris* hardware. When the RNC is in the ready state any task can be started.
472230557Sjimharris*
473230557Sjimharris* @param[in] this_rnc The rnc for which the task request is targeted.
474230557Sjimharris* @param[in] the_request The request which is going to be started.
475230557Sjimharris*
476230557Sjimharris* @return SCI_STATUS
477230557Sjimharris* @retval SCI_SUCCESS
478230557Sjimharris*/
479230557Sjimharrisstatic
480230557SjimharrisSCI_STATUS scic_sds_remote_node_context_success_start_task_handler(
481230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
482230557Sjimharris   struct SCIC_SDS_REQUEST             * the_request
483230557Sjimharris)
484230557Sjimharris{
485230557Sjimharris   return SCI_SUCCESS;
486230557Sjimharris}
487230557Sjimharris
488230557Sjimharris/**
489230557Sjimharris* This method handles destruct calls from the various state handlers.  The
490230557Sjimharris* remote node context can be requested to destroy from any state. If there
491230557Sjimharris* was a user callback it is always replaced with the request to destroy user
492230557Sjimharris* callback.
493230557Sjimharris*
494230557Sjimharris* @param[in] this_rnc
495230557Sjimharris* @param[in] the_callback
496230557Sjimharris* @param[in] callback_parameter
497230557Sjimharris*
498230557Sjimharris* @return SCI_STATUS
499230557Sjimharris*/
500230557Sjimharrisstatic
501230557SjimharrisSCI_STATUS scic_sds_remote_node_context_general_destruct_handler(
502230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
503230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
504230557Sjimharris   void                                   * callback_parameter
505230557Sjimharris)
506230557Sjimharris{
507230557Sjimharris   scic_sds_remote_node_context_setup_to_destory(
508230557Sjimharris      this_rnc, the_callback, callback_parameter
509230557Sjimharris         );
510230557Sjimharris
511230557Sjimharris   sci_base_state_machine_change_state(
512230557Sjimharris      &this_rnc->state_machine,
513230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE
514230557Sjimharris         );
515230557Sjimharris
516230557Sjimharris   return SCI_SUCCESS;
517230557Sjimharris}
518230557Sjimharris// ---------------------------------------------------------------------------
519230557Sjimharrisstatic
520230557SjimharrisSCI_STATUS scic_sds_remote_node_context_reset_required_start_io_handler(
521230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
522230557Sjimharris   struct SCIC_SDS_REQUEST             * the_request
523230557Sjimharris)
524230557Sjimharris{
525230557Sjimharris   SCIC_LOG_WARNING((
526230557Sjimharris      sci_base_object_get_logger(this_rnc->device),
527230557Sjimharris      SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
528230557Sjimharris         SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
529230557Sjimharris         SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
530230557Sjimharris      "SCIC Remote Node Context 0x%x requested to start io 0x%x while in wrong state %d\n",
531230557Sjimharris      this_rnc, the_request, sci_base_state_machine_get_state(&this_rnc->state_machine)
532230557Sjimharris         ));
533230557Sjimharris
534230557Sjimharris   return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
535230557Sjimharris}
536230557Sjimharris
537230557Sjimharris// ---------------------------------------------------------------------------
538230557Sjimharris
539230557Sjimharrisstatic
540230557SjimharrisSCI_STATUS scic_sds_remote_node_context_initial_state_resume_handler(
541230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
542230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
543230557Sjimharris   void                                   * callback_parameter
544230557Sjimharris)
545230557Sjimharris{
546230557Sjimharris   if (this_rnc->remote_node_index != SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
547230557Sjimharris   {
548230557Sjimharris      scic_sds_remote_node_context_setup_to_resume(
549230557Sjimharris         this_rnc, the_callback, callback_parameter
550230557Sjimharris            );
551230557Sjimharris
552230557Sjimharris      scic_sds_remote_node_context_construct_buffer(this_rnc);
553230557Sjimharris
554230557Sjimharris#if defined (SCI_LOGGING)
555230557Sjimharris      // If a remote node context has a logger already, don't work on its state
556230557Sjimharris      // logging.
557230557Sjimharris      if (this_rnc->state_machine.previous_state_id
558230557Sjimharris             != SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE)
559230557Sjimharris         scic_sds_remote_node_context_initialize_state_logging(this_rnc);
560230557Sjimharris#endif
561230557Sjimharris
562230557Sjimharris      sci_base_state_machine_change_state(
563230557Sjimharris         &this_rnc->state_machine,
564230557Sjimharris         SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE
565230557Sjimharris            );
566230557Sjimharris
567230557Sjimharris      return SCI_SUCCESS;
568230557Sjimharris   }
569230557Sjimharris
570230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
571230557Sjimharris}
572230557Sjimharris
573230557Sjimharris// ---------------------------------------------------------------------------
574230557Sjimharris
575230557Sjimharrisstatic
576230557SjimharrisSCI_STATUS scic_sds_remote_node_context_posting_state_event_handler(
577230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
578230557Sjimharris   U32                                   event_code
579230557Sjimharris)
580230557Sjimharris{
581230557Sjimharris   SCI_STATUS status;
582230557Sjimharris
583230557Sjimharris   switch (scu_get_event_code(event_code))
584230557Sjimharris   {
585230557Sjimharris      case SCU_EVENT_POST_RNC_COMPLETE:
586230557Sjimharris         status = SCI_SUCCESS;
587230557Sjimharris
588230557Sjimharris         sci_base_state_machine_change_state(
589230557Sjimharris            &this_rnc->state_machine,
590230557Sjimharris            SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE
591230557Sjimharris               );
592230557Sjimharris         break;
593230557Sjimharris
594230557Sjimharris      default:
595230557Sjimharris         status = SCI_FAILURE;
596230557Sjimharris         SCIC_LOG_WARNING((
597230557Sjimharris            sci_base_object_get_logger(this_rnc->device),
598230557Sjimharris            SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
599230557Sjimharris               SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
600230557Sjimharris               SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
601230557Sjimharris            "SCIC Remote Node Context 0x%x requested to process unexpected event 0x%x while in posting state\n",
602230557Sjimharris            this_rnc, event_code
603230557Sjimharris               ));
604230557Sjimharris         break;
605230557Sjimharris   }
606230557Sjimharris
607230557Sjimharris   return status;
608230557Sjimharris}
609230557Sjimharris
610230557Sjimharris// ---------------------------------------------------------------------------
611230557Sjimharris
612230557Sjimharrisstatic
613230557SjimharrisSCI_STATUS scic_sds_remote_node_context_invalidating_state_destruct_handler(
614230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
615230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
616230557Sjimharris   void                                   * callback_parameter
617230557Sjimharris)
618230557Sjimharris{
619230557Sjimharris   scic_sds_remote_node_context_setup_to_destory(
620230557Sjimharris      this_rnc, the_callback, callback_parameter
621230557Sjimharris         );
622230557Sjimharris
623230557Sjimharris   return SCI_SUCCESS;
624230557Sjimharris}
625230557Sjimharris
626230557Sjimharrisstatic
627230557SjimharrisSCI_STATUS scic_sds_remote_node_context_invalidating_state_event_handler(
628230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc,
629230557Sjimharris   U32                              event_code
630230557Sjimharris)
631230557Sjimharris{
632230557Sjimharris   SCI_STATUS status;
633230557Sjimharris
634230557Sjimharris   if (scu_get_event_code(event_code) == SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE)
635230557Sjimharris   {
636230557Sjimharris      status = SCI_SUCCESS;
637230557Sjimharris
638230557Sjimharris      if (this_rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL)
639230557Sjimharris      {
640230557Sjimharris         sci_base_state_machine_change_state(
641230557Sjimharris            &this_rnc->state_machine,
642230557Sjimharris            SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE
643230557Sjimharris               );
644230557Sjimharris      }
645230557Sjimharris      else
646230557Sjimharris      {
647230557Sjimharris         sci_base_state_machine_change_state(
648230557Sjimharris            &this_rnc->state_machine,
649230557Sjimharris            SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE
650230557Sjimharris               );
651230557Sjimharris      }
652230557Sjimharris   }
653230557Sjimharris   else
654230557Sjimharris   {
655230557Sjimharris      switch (scu_get_event_type(event_code))
656230557Sjimharris      {
657230557Sjimharris         case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
658230557Sjimharris         case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
659230557Sjimharris            // We really dont care if the hardware is going to suspend
660230557Sjimharris            // the device since it's being invalidated anyway
661230557Sjimharris            SCIC_LOG_INFO((
662230557Sjimharris               sci_base_object_get_logger(this_rnc->device),
663230557Sjimharris               SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
664230557Sjimharris                  SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
665230557Sjimharris                  SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
666230557Sjimharris               "SCIC Remote Node Context 0x%x was suspeneded by hardware while being invalidated.\n",
667230557Sjimharris               this_rnc
668230557Sjimharris                  ));
669230557Sjimharris            status = SCI_SUCCESS;
670230557Sjimharris            break;
671230557Sjimharris
672230557Sjimharris         default:
673230557Sjimharris            SCIC_LOG_WARNING((
674230557Sjimharris               sci_base_object_get_logger(this_rnc->device),
675230557Sjimharris               SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
676230557Sjimharris                  SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
677230557Sjimharris                  SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
678230557Sjimharris               "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n",
679230557Sjimharris               this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine)
680230557Sjimharris                  ));
681230557Sjimharris            status = SCI_FAILURE;
682230557Sjimharris            break;
683230557Sjimharris      }
684230557Sjimharris   }
685230557Sjimharris
686230557Sjimharris   return status;
687230557Sjimharris}
688230557Sjimharris
689230557Sjimharris// ---------------------------------------------------------------------------
690230557Sjimharris
691230557Sjimharrisstatic
692230557SjimharrisSCI_STATUS scic_sds_remote_node_context_resuming_state_event_handler(
693230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
694230557Sjimharris   U32                                   event_code
695230557Sjimharris)
696230557Sjimharris{
697230557Sjimharris   SCI_STATUS status;
698230557Sjimharris
699230557Sjimharris   if (scu_get_event_code(event_code) == SCU_EVENT_POST_RCN_RELEASE)
700230557Sjimharris   {
701230557Sjimharris      status = SCI_SUCCESS;
702230557Sjimharris
703230557Sjimharris      sci_base_state_machine_change_state(
704230557Sjimharris         &this_rnc->state_machine,
705230557Sjimharris         SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE
706230557Sjimharris            );
707230557Sjimharris   }
708230557Sjimharris   else
709230557Sjimharris   {
710230557Sjimharris      switch (scu_get_event_type(event_code))
711230557Sjimharris      {
712230557Sjimharris         case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
713230557Sjimharris         case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
714230557Sjimharris            // We really dont care if the hardware is going to suspend
715230557Sjimharris            // the device since it's being resumed anyway
716230557Sjimharris            SCIC_LOG_INFO((
717230557Sjimharris               sci_base_object_get_logger(this_rnc->device),
718230557Sjimharris               SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
719230557Sjimharris                  SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
720230557Sjimharris                  SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
721230557Sjimharris               "SCIC Remote Node Context 0x%x was suspeneded by hardware while being resumed.\n",
722230557Sjimharris               this_rnc
723230557Sjimharris                  ));
724230557Sjimharris            status = SCI_SUCCESS;
725230557Sjimharris            break;
726230557Sjimharris
727230557Sjimharris         default:
728230557Sjimharris            SCIC_LOG_WARNING((
729230557Sjimharris               sci_base_object_get_logger(this_rnc->device),
730230557Sjimharris               SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
731230557Sjimharris                  SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
732230557Sjimharris                  SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
733230557Sjimharris               "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n",
734230557Sjimharris               this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine)
735230557Sjimharris                  ));
736230557Sjimharris            status = SCI_FAILURE;
737230557Sjimharris            break;
738230557Sjimharris      }
739230557Sjimharris   }
740230557Sjimharris
741230557Sjimharris   return status;
742230557Sjimharris}
743230557Sjimharris
744230557Sjimharris// ---------------------------------------------------------------------------
745230557Sjimharris
746230557Sjimharris/**
747230557Sjimharris* This method will handle the suspend requests from the ready state.
748230557Sjimharris*
749230557Sjimharris* @param[in] this_rnc The remote node context object being suspended.
750230557Sjimharris* @param[in] the_callback The callback when the suspension is complete.
751230557Sjimharris* @param[in] callback_parameter The parameter that is to be passed into the
752230557Sjimharris*       callback.
753230557Sjimharris*
754230557Sjimharris* @return SCI_SUCCESS
755230557Sjimharris*/
756230557Sjimharrisstatic
757230557SjimharrisSCI_STATUS scic_sds_remote_node_context_ready_state_suspend_handler(
758230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
759230557Sjimharris   U32                                      suspend_type,
760230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
761230557Sjimharris   void                                   * callback_parameter
762230557Sjimharris)
763230557Sjimharris{
764230557Sjimharris   this_rnc->user_callback   = the_callback;
765230557Sjimharris   this_rnc->user_cookie     = callback_parameter;
766230557Sjimharris   this_rnc->suspension_code = suspend_type;
767230557Sjimharris
768230557Sjimharris   if (suspend_type == SCI_SOFTWARE_SUSPENSION)
769230557Sjimharris   {
770230557Sjimharris      scic_sds_remote_device_post_request(
771230557Sjimharris         this_rnc->device,
772230557Sjimharris         SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX
773230557Sjimharris            );
774230557Sjimharris   }
775230557Sjimharris
776230557Sjimharris   sci_base_state_machine_change_state(
777230557Sjimharris      &this_rnc->state_machine,
778230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE
779230557Sjimharris         );
780230557Sjimharris
781230557Sjimharris   return SCI_SUCCESS;
782230557Sjimharris}
783230557Sjimharris
784230557Sjimharris/**
785230557Sjimharris* This method determines if the io request can be started by the SCU
786230557Sjimharris* hardware. When the RNC is in the ready state any io request can be started.
787230557Sjimharris*
788230557Sjimharris* @param[in] this_rnc The rnc for which the io request is targeted.
789230557Sjimharris* @param[in] the_request The request which is going to be started.
790230557Sjimharris*
791230557Sjimharris* @return SCI_STATUS
792230557Sjimharris* @retval SCI_SUCCESS
793230557Sjimharris*/
794230557Sjimharrisstatic
795230557SjimharrisSCI_STATUS scic_sds_remote_node_context_ready_state_start_io_handler(
796230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
797230557Sjimharris   struct SCIC_SDS_REQUEST             * the_request
798230557Sjimharris)
799230557Sjimharris{
800230557Sjimharris   return SCI_SUCCESS;
801230557Sjimharris}
802230557Sjimharris
803230557Sjimharris
804230557Sjimharrisstatic
805230557SjimharrisSCI_STATUS scic_sds_remote_node_context_ready_state_event_handler(
806230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
807230557Sjimharris   U32                                   event_code
808230557Sjimharris)
809230557Sjimharris{
810230557Sjimharris   SCI_STATUS status;
811230557Sjimharris
812230557Sjimharris   switch (scu_get_event_type(event_code))
813230557Sjimharris   {
814230557Sjimharris      case SCU_EVENT_TL_RNC_SUSPEND_TX:
815230557Sjimharris         sci_base_state_machine_change_state(
816230557Sjimharris            &this_rnc->state_machine,
817230557Sjimharris            SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE
818230557Sjimharris               );
819230557Sjimharris
820230557Sjimharris         this_rnc->suspension_code = scu_get_event_specifier(event_code);
821230557Sjimharris         status = SCI_SUCCESS;
822230557Sjimharris         break;
823230557Sjimharris
824230557Sjimharris      case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
825230557Sjimharris         sci_base_state_machine_change_state(
826230557Sjimharris            &this_rnc->state_machine,
827230557Sjimharris            SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE
828230557Sjimharris               );
829230557Sjimharris
830230557Sjimharris         this_rnc->suspension_code = scu_get_event_specifier(event_code);
831230557Sjimharris         status = SCI_SUCCESS;
832230557Sjimharris         break;
833230557Sjimharris
834230557Sjimharris      default:
835230557Sjimharris         SCIC_LOG_WARNING((
836230557Sjimharris            sci_base_object_get_logger(this_rnc->device),
837230557Sjimharris            SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
838230557Sjimharris               SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
839230557Sjimharris               SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
840230557Sjimharris            "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n",
841230557Sjimharris            this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine)
842230557Sjimharris               ));
843230557Sjimharris
844230557Sjimharris         status = SCI_FAILURE;
845230557Sjimharris         break;
846230557Sjimharris   }
847230557Sjimharris
848230557Sjimharris   return status;
849230557Sjimharris}
850230557Sjimharris
851230557Sjimharris// ---------------------------------------------------------------------------
852230557Sjimharris
853230557Sjimharrisstatic
854230557SjimharrisSCI_STATUS scic_sds_remote_node_context_tx_suspended_state_resume_handler(
855230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
856230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
857230557Sjimharris   void                                   * callback_parameter
858230557Sjimharris)
859230557Sjimharris{
860230557Sjimharris   SMP_DISCOVER_RESPONSE_PROTOCOLS_T protocols;
861230557Sjimharris
862230557Sjimharris   scic_sds_remote_node_context_setup_to_resume(
863230557Sjimharris      this_rnc, the_callback, callback_parameter
864230557Sjimharris         );
865230557Sjimharris
866230557Sjimharris   // If this is an expander attached SATA device we must invalidate
867230557Sjimharris   // and repost the RNC since this is the only way to clear the
868230557Sjimharris   // TCi to NCQ tag mapping table for the RNi
869230557Sjimharris   // All other device types we can just resume.
870230557Sjimharris   scic_remote_device_get_protocols(this_rnc->device, &protocols);
871230557Sjimharris
872230557Sjimharris   if (
873230557Sjimharris      (protocols.u.bits.attached_stp_target == 1)
874230557Sjimharris         && !(this_rnc->device->is_direct_attached)
875230557Sjimharris         )
876230557Sjimharris   {
877230557Sjimharris      sci_base_state_machine_change_state(
878230557Sjimharris         &this_rnc->state_machine,
879230557Sjimharris         SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE
880230557Sjimharris            );
881230557Sjimharris   }
882230557Sjimharris   else
883230557Sjimharris   {
884230557Sjimharris      sci_base_state_machine_change_state(
885230557Sjimharris         &this_rnc->state_machine,
886230557Sjimharris         SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE
887230557Sjimharris            );
888230557Sjimharris   }
889230557Sjimharris
890230557Sjimharris   return SCI_SUCCESS;
891230557Sjimharris}
892230557Sjimharris
893230557Sjimharris/**
894230557Sjimharris* This method will report a success or failure attempt to start a new task
895230557Sjimharris* request to the hardware.  Since all task requests are sent on the high
896230557Sjimharris* priority queue they can be sent when the RCN is in a TX suspend state.
897230557Sjimharris*
898230557Sjimharris* @param[in] this_rnc The remote node context which is to receive the task
899230557Sjimharris*       request.
900230557Sjimharris* @param[in] the_request The task request to be transmitted to to the remote
901230557Sjimharris*       target device.
902230557Sjimharris*
903230557Sjimharris* @return SCI_STATUS
904230557Sjimharris* @retval SCI_SUCCESS
905230557Sjimharris*/
906230557Sjimharrisstatic
907230557SjimharrisSCI_STATUS scic_sds_remote_node_context_suspended_start_task_handler(
908230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
909230557Sjimharris   struct SCIC_SDS_REQUEST             * the_request
910230557Sjimharris)
911230557Sjimharris{
912230557Sjimharris   scic_sds_remote_node_context_resume(this_rnc, NULL, NULL);
913230557Sjimharris
914230557Sjimharris   return SCI_SUCCESS;
915230557Sjimharris}
916230557Sjimharris
917230557Sjimharris// ---------------------------------------------------------------------------
918230557Sjimharris
919230557Sjimharrisstatic
920230557SjimharrisSCI_STATUS scic_sds_remote_node_context_tx_rx_suspended_state_resume_handler(
921230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
922230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
923230557Sjimharris   void                                   * callback_parameter
924230557Sjimharris)
925230557Sjimharris{
926230557Sjimharris   scic_sds_remote_node_context_setup_to_resume(
927230557Sjimharris      this_rnc, the_callback, callback_parameter
928230557Sjimharris         );
929230557Sjimharris
930230557Sjimharris   sci_base_state_machine_change_state(
931230557Sjimharris      &this_rnc->state_machine,
932230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE
933230557Sjimharris         );
934230557Sjimharris
935230557Sjimharris   return SCI_FAILURE_INVALID_STATE;
936230557Sjimharris}
937230557Sjimharris
938230557Sjimharris// ---------------------------------------------------------------------------
939230557Sjimharris
940230557Sjimharris/**
941230557Sjimharris*
942230557Sjimharris*/
943230557Sjimharrisstatic
944230557SjimharrisSCI_STATUS scic_sds_remote_node_context_await_suspension_state_resume_handler(
945230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T         * this_rnc,
946230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
947230557Sjimharris   void                                   * callback_parameter
948230557Sjimharris)
949230557Sjimharris{
950230557Sjimharris   scic_sds_remote_node_context_setup_to_resume(
951230557Sjimharris      this_rnc, the_callback, callback_parameter
952230557Sjimharris         );
953230557Sjimharris
954230557Sjimharris   return SCI_SUCCESS;
955230557Sjimharris}
956230557Sjimharris
957230557Sjimharris/**
958230557Sjimharris* This method will report a success or failure attempt to start a new task
959230557Sjimharris* request to the hardware.  Since all task requests are sent on the high
960230557Sjimharris* priority queue they can be sent when the RCN is in a TX suspend state.
961230557Sjimharris*
962230557Sjimharris* @param[in] this_rnc The remote node context which is to receive the task
963230557Sjimharris*       request.
964230557Sjimharris* @param[in] the_request The task request to be transmitted to to the remote
965230557Sjimharris*       target device.
966230557Sjimharris*
967230557Sjimharris* @return SCI_STATUS
968230557Sjimharris* @retval SCI_SUCCESS
969230557Sjimharris*/
970230557Sjimharrisstatic
971230557SjimharrisSCI_STATUS scic_sds_remote_node_context_await_suspension_state_start_task_handler(
972230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
973230557Sjimharris   struct SCIC_SDS_REQUEST             * the_request
974230557Sjimharris)
975230557Sjimharris{
976230557Sjimharris   return SCI_SUCCESS;
977230557Sjimharris}
978230557Sjimharris
979230557Sjimharrisstatic
980230557SjimharrisSCI_STATUS scic_sds_remote_node_context_await_suspension_state_event_handler(
981230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
982230557Sjimharris   U32                                   event_code
983230557Sjimharris)
984230557Sjimharris{
985230557Sjimharris   SCI_STATUS status;
986230557Sjimharris
987230557Sjimharris   switch (scu_get_event_type(event_code))
988230557Sjimharris   {
989230557Sjimharris      case SCU_EVENT_TL_RNC_SUSPEND_TX:
990230557Sjimharris         sci_base_state_machine_change_state(
991230557Sjimharris            &this_rnc->state_machine,
992230557Sjimharris            SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE
993230557Sjimharris               );
994230557Sjimharris
995230557Sjimharris         this_rnc->suspension_code = scu_get_event_specifier(event_code);
996230557Sjimharris         status = SCI_SUCCESS;
997230557Sjimharris         break;
998230557Sjimharris
999230557Sjimharris      case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
1000230557Sjimharris         sci_base_state_machine_change_state(
1001230557Sjimharris            &this_rnc->state_machine,
1002230557Sjimharris            SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE
1003230557Sjimharris               );
1004230557Sjimharris
1005230557Sjimharris         this_rnc->suspension_code = scu_get_event_specifier(event_code);
1006230557Sjimharris         status = SCI_SUCCESS;
1007230557Sjimharris         break;
1008230557Sjimharris
1009230557Sjimharris      default:
1010230557Sjimharris         SCIC_LOG_WARNING((
1011230557Sjimharris            sci_base_object_get_logger(this_rnc->device),
1012230557Sjimharris            SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
1013230557Sjimharris               SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
1014230557Sjimharris               SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
1015230557Sjimharris            "SCIC Remote Node Context 0x%x requested to process event 0x%x while in state %d.\n",
1016230557Sjimharris            this_rnc, event_code, sci_base_state_machine_get_state(&this_rnc->state_machine)
1017230557Sjimharris               ));
1018230557Sjimharris
1019230557Sjimharris         status = SCI_FAILURE;
1020230557Sjimharris         break;
1021230557Sjimharris   }
1022230557Sjimharris
1023230557Sjimharris   return status;
1024230557Sjimharris}
1025230557Sjimharris
1026230557Sjimharris// ---------------------------------------------------------------------------
1027230557Sjimharris
1028230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS
1029230557Sjimharris   scic_sds_remote_node_context_state_handler_table[
1030230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES] =
1031230557Sjimharris{
1032230557Sjimharris   // SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE
1033230557Sjimharris   {
1034230557Sjimharris      scic_sds_remote_node_context_default_destruct_handler,
1035230557Sjimharris      scic_sds_remote_node_context_default_suspend_handler,
1036230557Sjimharris      scic_sds_remote_node_context_initial_state_resume_handler,
1037230557Sjimharris      scic_sds_remote_node_context_default_start_io_handler,
1038230557Sjimharris      scic_sds_remote_node_context_default_start_task_handler,
1039230557Sjimharris      scic_sds_remote_node_context_default_event_handler
1040230557Sjimharris   },
1041230557Sjimharris   // SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE
1042230557Sjimharris   {
1043230557Sjimharris      scic_sds_remote_node_context_general_destruct_handler,
1044230557Sjimharris      scic_sds_remote_node_context_default_suspend_handler,
1045230557Sjimharris      scic_sds_remote_node_context_continue_to_resume_handler,
1046230557Sjimharris      scic_sds_remote_node_context_default_start_io_handler,
1047230557Sjimharris      scic_sds_remote_node_context_default_start_task_handler,
1048230557Sjimharris      scic_sds_remote_node_context_posting_state_event_handler
1049230557Sjimharris   },
1050230557Sjimharris   // SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE
1051230557Sjimharris   {
1052230557Sjimharris      scic_sds_remote_node_context_invalidating_state_destruct_handler,
1053230557Sjimharris      scic_sds_remote_node_context_default_suspend_handler,
1054230557Sjimharris      scic_sds_remote_node_context_continue_to_resume_handler,
1055230557Sjimharris      scic_sds_remote_node_context_default_start_io_handler,
1056230557Sjimharris      scic_sds_remote_node_context_default_start_task_handler,
1057230557Sjimharris      scic_sds_remote_node_context_invalidating_state_event_handler
1058230557Sjimharris   },
1059230557Sjimharris   // SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE
1060230557Sjimharris   {
1061230557Sjimharris      scic_sds_remote_node_context_general_destruct_handler,
1062230557Sjimharris      scic_sds_remote_node_context_default_suspend_handler,
1063230557Sjimharris      scic_sds_remote_node_context_continue_to_resume_handler,
1064230557Sjimharris      scic_sds_remote_node_context_default_start_io_handler,
1065230557Sjimharris      scic_sds_remote_node_context_success_start_task_handler,
1066230557Sjimharris      scic_sds_remote_node_context_resuming_state_event_handler
1067230557Sjimharris   },
1068230557Sjimharris   // SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE
1069230557Sjimharris   {
1070230557Sjimharris      scic_sds_remote_node_context_general_destruct_handler,
1071230557Sjimharris      scic_sds_remote_node_context_ready_state_suspend_handler,
1072230557Sjimharris      scic_sds_remote_node_context_default_resume_handler,
1073230557Sjimharris      scic_sds_remote_node_context_ready_state_start_io_handler,
1074230557Sjimharris      scic_sds_remote_node_context_success_start_task_handler,
1075230557Sjimharris      scic_sds_remote_node_context_ready_state_event_handler
1076230557Sjimharris   },
1077230557Sjimharris   // SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE
1078230557Sjimharris   {
1079230557Sjimharris      scic_sds_remote_node_context_general_destruct_handler,
1080230557Sjimharris      scic_sds_remote_node_context_default_suspend_handler,
1081230557Sjimharris      scic_sds_remote_node_context_tx_suspended_state_resume_handler,
1082230557Sjimharris      scic_sds_remote_node_context_reset_required_start_io_handler,
1083230557Sjimharris      scic_sds_remote_node_context_suspended_start_task_handler,
1084230557Sjimharris      scic_sds_remote_node_context_default_event_handler
1085230557Sjimharris   },
1086230557Sjimharris   // SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE
1087230557Sjimharris   {
1088230557Sjimharris      scic_sds_remote_node_context_general_destruct_handler,
1089230557Sjimharris      scic_sds_remote_node_context_default_suspend_handler,
1090230557Sjimharris      scic_sds_remote_node_context_tx_rx_suspended_state_resume_handler,
1091230557Sjimharris      scic_sds_remote_node_context_reset_required_start_io_handler,
1092230557Sjimharris      scic_sds_remote_node_context_suspended_start_task_handler,
1093230557Sjimharris      scic_sds_remote_node_context_default_event_handler
1094230557Sjimharris   },
1095230557Sjimharris   // SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE
1096230557Sjimharris   {
1097230557Sjimharris      scic_sds_remote_node_context_general_destruct_handler,
1098230557Sjimharris      scic_sds_remote_node_context_default_suspend_handler,
1099230557Sjimharris      scic_sds_remote_node_context_await_suspension_state_resume_handler,
1100230557Sjimharris      scic_sds_remote_node_context_reset_required_start_io_handler,
1101230557Sjimharris      scic_sds_remote_node_context_await_suspension_state_start_task_handler,
1102230557Sjimharris      scic_sds_remote_node_context_await_suspension_state_event_handler
1103230557Sjimharris   }
1104230557Sjimharris};
1105230557Sjimharris
1106230557Sjimharris//*****************************************************************************
1107230557Sjimharris//* REMOTE NODE CONTEXT PRIVATE METHODS
1108230557Sjimharris//*****************************************************************************
1109230557Sjimharris
1110230557Sjimharris/**
1111230557Sjimharris* This method just calls the user callback function and then resets the
1112230557Sjimharris* callback.
1113230557Sjimharris*
1114230557Sjimharris* @param[in out] rnc
1115230557Sjimharris*/
1116230557Sjimharrisstatic
1117230557Sjimharrisvoid scic_sds_remote_node_context_notify_user(
1118230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T *rnc
1119230557Sjimharris)
1120230557Sjimharris{
1121230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK local_user_callback = rnc->user_callback;
1122230557Sjimharris   void * local_user_cookie = rnc->user_cookie;
1123230557Sjimharris
1124230557Sjimharris   //we need to set the user_callback to NULL before it is called, because
1125230557Sjimharris   //the user callback's stack may eventually also set up a new set of
1126230557Sjimharris   //user callback. If we nullify the user_callback after it is called,
1127230557Sjimharris   //we are in the risk to lose the freshly set user callback.
1128230557Sjimharris   rnc->user_callback = NULL;
1129230557Sjimharris   rnc->user_cookie = NULL;
1130230557Sjimharris
1131230557Sjimharris   if (local_user_callback != NULL)
1132230557Sjimharris   {
1133230557Sjimharris      (*local_user_callback)(local_user_cookie);
1134230557Sjimharris   }
1135230557Sjimharris}
1136230557Sjimharris
1137230557Sjimharris/**
1138230557Sjimharris* This method will continue the remote node context state machine by
1139230557Sjimharris* requesting to resume the remote node context state machine from its current
1140230557Sjimharris* state.
1141230557Sjimharris*
1142230557Sjimharris* @param[in] rnc
1143230557Sjimharris*/
1144230557Sjimharrisstatic
1145230557Sjimharrisvoid scic_sds_remote_node_context_continue_state_transitions(
1146230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc
1147230557Sjimharris)
1148230557Sjimharris{
1149230557Sjimharris   if (rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY)
1150230557Sjimharris   {
1151230557Sjimharris      rnc->state_handlers->resume_handler(
1152230557Sjimharris         rnc, rnc->user_callback, rnc->user_cookie
1153230557Sjimharris            );
1154230557Sjimharris   }
1155230557Sjimharris}
1156230557Sjimharris
1157230557Sjimharris/**
1158230557Sjimharris* This method will mark the rnc buffer as being valid and post the request to
1159230557Sjimharris* the hardware.
1160230557Sjimharris*
1161230557Sjimharris* @param[in] this_rnc The remote node context object that is to be
1162230557Sjimharris*            validated.
1163230557Sjimharris*
1164230557Sjimharris* @return none
1165230557Sjimharris*/
1166230557Sjimharrisstatic
1167230557Sjimharrisvoid scic_sds_remote_node_context_validate_context_buffer(
1168230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
1169230557Sjimharris)
1170230557Sjimharris{
1171230557Sjimharris   SCU_REMOTE_NODE_CONTEXT_T *rnc_buffer;
1172230557Sjimharris
1173230557Sjimharris   rnc_buffer = scic_sds_controller_get_remote_node_context_buffer(
1174230557Sjimharris      scic_sds_remote_device_get_controller(this_rnc->device),
1175230557Sjimharris      this_rnc->remote_node_index
1176230557Sjimharris         );
1177230557Sjimharris
1178230557Sjimharris   rnc_buffer->ssp.is_valid = TRUE;
1179230557Sjimharris
1180230557Sjimharris   if (
1181230557Sjimharris      !this_rnc->device->is_direct_attached
1182230557Sjimharris         && this_rnc->device->target_protocols.u.bits.attached_stp_target
1183230557Sjimharris         )
1184230557Sjimharris   {
1185230557Sjimharris      scic_sds_remote_device_post_request(
1186230557Sjimharris         this_rnc->device,
1187230557Sjimharris         SCU_CONTEXT_COMMAND_POST_RNC_96
1188230557Sjimharris            );
1189230557Sjimharris   }
1190230557Sjimharris   else
1191230557Sjimharris   {
1192230557Sjimharris      scic_sds_remote_device_post_request(
1193230557Sjimharris         this_rnc->device,
1194230557Sjimharris         SCU_CONTEXT_COMMAND_POST_RNC_32
1195230557Sjimharris            );
1196230557Sjimharris
1197230557Sjimharris      if (this_rnc->device->is_direct_attached)
1198230557Sjimharris      {
1199230557Sjimharris         scic_sds_port_setup_transports(
1200230557Sjimharris            this_rnc->device->owning_port,
1201230557Sjimharris            this_rnc->remote_node_index
1202230557Sjimharris               );
1203230557Sjimharris      }
1204230557Sjimharris   }
1205230557Sjimharris}
1206230557Sjimharris
1207230557Sjimharris/**
1208230557Sjimharris* This method will update the RNC buffer and post the invalidate request.
1209230557Sjimharris*
1210230557Sjimharris* @param[in] this_rnc The remote node context object that is to be
1211230557Sjimharris*       invalidated.
1212230557Sjimharris*
1213230557Sjimharris* @return none
1214230557Sjimharris*/
1215230557Sjimharrisstatic
1216230557Sjimharrisvoid scic_sds_remote_node_context_invalidate_context_buffer(
1217230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
1218230557Sjimharris)
1219230557Sjimharris{
1220230557Sjimharris   SCU_REMOTE_NODE_CONTEXT_T *rnc_buffer;
1221230557Sjimharris
1222230557Sjimharris   rnc_buffer = scic_sds_controller_get_remote_node_context_buffer(
1223230557Sjimharris      scic_sds_remote_device_get_controller(this_rnc->device),
1224230557Sjimharris      this_rnc->remote_node_index
1225230557Sjimharris         );
1226230557Sjimharris
1227230557Sjimharris   rnc_buffer->ssp.is_valid = FALSE;
1228230557Sjimharris
1229230557Sjimharris   scic_sds_remote_device_post_request(
1230230557Sjimharris      this_rnc->device,
1231230557Sjimharris      SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE
1232230557Sjimharris         );
1233230557Sjimharris}
1234230557Sjimharris
1235230557Sjimharris//*****************************************************************************
1236230557Sjimharris//* REMOTE NODE CONTEXT STATE ENTER AND EXIT METHODS
1237230557Sjimharris//*****************************************************************************
1238230557Sjimharris
1239230557Sjimharris/**
1240230557Sjimharris*
1241230557Sjimharris*
1242230557Sjimharris* @param[in] object
1243230557Sjimharris*/
1244230557Sjimharrisstatic
1245230557Sjimharrisvoid scic_sds_remote_node_context_initial_state_enter(
1246230557Sjimharris   SCI_BASE_OBJECT_T * object
1247230557Sjimharris)
1248230557Sjimharris{
1249230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc;
1250230557Sjimharris   rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T  *)object;
1251230557Sjimharris
1252230557Sjimharris   SET_STATE_HANDLER(
1253230557Sjimharris      rnc,
1254230557Sjimharris      scic_sds_remote_node_context_state_handler_table,
1255230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE
1256230557Sjimharris         );
1257230557Sjimharris
1258230557Sjimharris   // Check to see if we have gotten back to the initial state because someone
1259230557Sjimharris   // requested to destroy the remote node context object.
1260230557Sjimharris   if (
1261230557Sjimharris      rnc->state_machine.previous_state_id
1262230557Sjimharris         == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE
1263230557Sjimharris         )
1264230557Sjimharris   {
1265230557Sjimharris      rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
1266230557Sjimharris
1267230557Sjimharris      scic_sds_remote_node_context_notify_user(rnc);
1268230557Sjimharris
1269230557Sjimharris      // Since we are destroying the remote node context deinitialize the state logging
1270230557Sjimharris      // should we resume the remote node context the state logging will be reinitialized
1271230557Sjimharris      // on the resume handler.
1272230557Sjimharris      scic_sds_remote_node_context_deinitialize_state_logging(rnc);
1273230557Sjimharris   }
1274230557Sjimharris}
1275230557Sjimharris
1276230557Sjimharris/**
1277230557Sjimharris*
1278230557Sjimharris*
1279230557Sjimharris* @param[in] object
1280230557Sjimharris*/
1281230557Sjimharrisstatic
1282230557Sjimharrisvoid scic_sds_remote_node_context_posting_state_enter(
1283230557Sjimharris   SCI_BASE_OBJECT_T * object
1284230557Sjimharris)
1285230557Sjimharris{
1286230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc;
1287230557Sjimharris   this_rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T  *)object;
1288230557Sjimharris
1289230557Sjimharris   SET_STATE_HANDLER(
1290230557Sjimharris      this_rnc,
1291230557Sjimharris      scic_sds_remote_node_context_state_handler_table,
1292230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE
1293230557Sjimharris         );
1294230557Sjimharris
1295230557Sjimharris   scic_sds_remote_node_context_validate_context_buffer(this_rnc);
1296230557Sjimharris}
1297230557Sjimharris
1298230557Sjimharris/**
1299230557Sjimharris*
1300230557Sjimharris*
1301230557Sjimharris* @param[in] object
1302230557Sjimharris*/
1303230557Sjimharrisstatic
1304230557Sjimharrisvoid scic_sds_remote_node_context_invalidating_state_enter(
1305230557Sjimharris   SCI_BASE_OBJECT_T * object
1306230557Sjimharris)
1307230557Sjimharris{
1308230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc;
1309230557Sjimharris   rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T  *)object;
1310230557Sjimharris
1311230557Sjimharris   SET_STATE_HANDLER(
1312230557Sjimharris      rnc,
1313230557Sjimharris      scic_sds_remote_node_context_state_handler_table,
1314230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE
1315230557Sjimharris         );
1316230557Sjimharris
1317230557Sjimharris   scic_sds_remote_node_context_invalidate_context_buffer(rnc);
1318230557Sjimharris}
1319230557Sjimharris
1320230557Sjimharris/**
1321230557Sjimharris*
1322230557Sjimharris*
1323230557Sjimharris* @param[in] object
1324230557Sjimharris*/
1325230557Sjimharrisstatic
1326230557Sjimharrisvoid scic_sds_remote_node_context_resuming_state_enter(
1327230557Sjimharris   SCI_BASE_OBJECT_T * object
1328230557Sjimharris)
1329230557Sjimharris{
1330230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc;
1331230557Sjimharris   SMP_DISCOVER_RESPONSE_PROTOCOLS_T protocols;
1332230557Sjimharris   rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T  *)object;
1333230557Sjimharris
1334230557Sjimharris   SET_STATE_HANDLER(
1335230557Sjimharris      rnc,
1336230557Sjimharris      scic_sds_remote_node_context_state_handler_table,
1337230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE
1338230557Sjimharris         );
1339230557Sjimharris
1340230557Sjimharris   // For direct attached SATA devices we need to clear the TLCR
1341230557Sjimharris   // NCQ to TCi tag mapping on the phy and in cases where we
1342230557Sjimharris   // resume because of a target reset we also need to update
1343230557Sjimharris   // the STPTLDARNI register with the RNi of the device
1344230557Sjimharris   scic_remote_device_get_protocols(rnc->device, &protocols);
1345230557Sjimharris
1346230557Sjimharris   if (
1347230557Sjimharris      (protocols.u.bits.attached_stp_target == 1)
1348230557Sjimharris         && (rnc->device->is_direct_attached)
1349230557Sjimharris         )
1350230557Sjimharris   {
1351230557Sjimharris      scic_sds_port_setup_transports(
1352230557Sjimharris         rnc->device->owning_port, rnc->remote_node_index
1353230557Sjimharris            );
1354230557Sjimharris   }
1355230557Sjimharris
1356230557Sjimharris   scic_sds_remote_device_post_request(
1357230557Sjimharris      rnc->device,
1358230557Sjimharris      SCU_CONTEXT_COMMAND_POST_RNC_RESUME
1359230557Sjimharris         );
1360230557Sjimharris}
1361230557Sjimharris
1362230557Sjimharris/**
1363230557Sjimharris*
1364230557Sjimharris*
1365230557Sjimharris* @param[in] object
1366230557Sjimharris*/
1367230557Sjimharrisstatic
1368230557Sjimharrisvoid scic_sds_remote_node_context_ready_state_enter(
1369230557Sjimharris   SCI_BASE_OBJECT_T * object
1370230557Sjimharris)
1371230557Sjimharris{
1372230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc;
1373230557Sjimharris   rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T  *)object;
1374230557Sjimharris
1375230557Sjimharris   SET_STATE_HANDLER(
1376230557Sjimharris      rnc,
1377230557Sjimharris      scic_sds_remote_node_context_state_handler_table,
1378230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE
1379230557Sjimharris         );
1380230557Sjimharris
1381230557Sjimharris   rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
1382230557Sjimharris
1383230557Sjimharris   if (rnc->user_callback != NULL)
1384230557Sjimharris   {
1385230557Sjimharris      scic_sds_remote_node_context_notify_user(rnc);
1386230557Sjimharris   }
1387230557Sjimharris}
1388230557Sjimharris
1389230557Sjimharris/**
1390230557Sjimharris*
1391230557Sjimharris*
1392230557Sjimharris* @param[in] object
1393230557Sjimharris*/
1394230557Sjimharrisstatic
1395230557Sjimharrisvoid scic_sds_remote_node_context_tx_suspended_state_enter(
1396230557Sjimharris   SCI_BASE_OBJECT_T * object
1397230557Sjimharris)
1398230557Sjimharris{
1399230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc;
1400230557Sjimharris   rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T  *)object;
1401230557Sjimharris
1402230557Sjimharris   SET_STATE_HANDLER(
1403230557Sjimharris      rnc,
1404230557Sjimharris      scic_sds_remote_node_context_state_handler_table,
1405230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE
1406230557Sjimharris         );
1407230557Sjimharris
1408230557Sjimharris   scic_sds_remote_node_context_continue_state_transitions(rnc);
1409230557Sjimharris}
1410230557Sjimharris
1411230557Sjimharris/**
1412230557Sjimharris*
1413230557Sjimharris*
1414230557Sjimharris* @param[in] object
1415230557Sjimharris*/
1416230557Sjimharrisstatic
1417230557Sjimharrisvoid scic_sds_remote_node_context_tx_rx_suspended_state_enter(
1418230557Sjimharris   SCI_BASE_OBJECT_T * object
1419230557Sjimharris)
1420230557Sjimharris{
1421230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc;
1422230557Sjimharris   rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T  *)object;
1423230557Sjimharris
1424230557Sjimharris   SET_STATE_HANDLER(
1425230557Sjimharris      rnc,
1426230557Sjimharris      scic_sds_remote_node_context_state_handler_table,
1427230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE
1428230557Sjimharris         );
1429230557Sjimharris
1430230557Sjimharris   scic_sds_remote_node_context_continue_state_transitions(rnc);
1431230557Sjimharris}
1432230557Sjimharris
1433230557Sjimharris/**
1434230557Sjimharris*
1435230557Sjimharris*
1436230557Sjimharris* @param[in] object
1437230557Sjimharris*/
1438230557Sjimharrisstatic
1439230557Sjimharrisvoid scic_sds_remote_node_context_await_suspension_state_enter(
1440230557Sjimharris   SCI_BASE_OBJECT_T * object
1441230557Sjimharris)
1442230557Sjimharris{
1443230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc;
1444230557Sjimharris   rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T  *)object;
1445230557Sjimharris
1446230557Sjimharris   SET_STATE_HANDLER(
1447230557Sjimharris      rnc,
1448230557Sjimharris      scic_sds_remote_node_context_state_handler_table,
1449230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE
1450230557Sjimharris         );
1451230557Sjimharris}
1452230557Sjimharris
1453230557Sjimharris// ---------------------------------------------------------------------------
1454230557Sjimharris
1455230557Sjimharris   SCI_BASE_STATE_T
1456230557Sjimharris   scic_sds_remote_node_context_state_table[
1457230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES] =
1458230557Sjimharris{
1459230557Sjimharris   {
1460230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE,
1461230557Sjimharris      scic_sds_remote_node_context_initial_state_enter,
1462230557Sjimharris      NULL
1463230557Sjimharris   },
1464230557Sjimharris   {
1465230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE,
1466230557Sjimharris      scic_sds_remote_node_context_posting_state_enter,
1467230557Sjimharris      NULL
1468230557Sjimharris   },
1469230557Sjimharris   {
1470230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE,
1471230557Sjimharris      scic_sds_remote_node_context_invalidating_state_enter,
1472230557Sjimharris      NULL
1473230557Sjimharris   },
1474230557Sjimharris   {
1475230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE,
1476230557Sjimharris      scic_sds_remote_node_context_resuming_state_enter,
1477230557Sjimharris      NULL
1478230557Sjimharris   },
1479230557Sjimharris   {
1480230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE,
1481230557Sjimharris      scic_sds_remote_node_context_ready_state_enter,
1482230557Sjimharris      NULL
1483230557Sjimharris   },
1484230557Sjimharris   {
1485230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE,
1486230557Sjimharris      scic_sds_remote_node_context_tx_suspended_state_enter,
1487230557Sjimharris      NULL
1488230557Sjimharris   },
1489230557Sjimharris   {
1490230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE,
1491230557Sjimharris      scic_sds_remote_node_context_tx_rx_suspended_state_enter,
1492230557Sjimharris      NULL
1493230557Sjimharris   },
1494230557Sjimharris   {
1495230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE,
1496230557Sjimharris      scic_sds_remote_node_context_await_suspension_state_enter,
1497230557Sjimharris      NULL
1498230557Sjimharris   }
1499230557Sjimharris};
1500230557Sjimharris
1501