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 * $FreeBSD$
53230557Sjimharris */
54230557Sjimharris#ifndef _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
55230557Sjimharris#define _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
56230557Sjimharris
57230557Sjimharris/**
58230557Sjimharris * @file
59230557Sjimharris *
60230557Sjimharris * @brief This file contains the structures, constants, and prototypes
61230557Sjimharris *        associated with the remote node context in the silicon.  It
62230557Sjimharris *        exists to model and manage the remote node context in the silicon.
63230557Sjimharris */
64230557Sjimharris
65230557Sjimharris#ifdef __cplusplus
66230557Sjimharrisextern "C" {
67230557Sjimharris#endif // __cplusplus
68230557Sjimharris
69230557Sjimharris#include <dev/isci/scil/sci_types.h>
70230557Sjimharris#include <dev/isci/scil/sci_base_state.h>
71230557Sjimharris#include <dev/isci/scil/sci_base_state_machine.h>
72230557Sjimharris#include <dev/isci/scil/sci_base_state_machine_logger.h>
73230557Sjimharris
74230557Sjimharris// ---------------------------------------------------------------------------
75230557Sjimharris
76230557Sjimharris/**
77230557Sjimharris * This constant represents an invalid remote device id, it is used to program
78230557Sjimharris * the STPDARNI register so the driver knows when it has received a SIGNATURE
79230557Sjimharris * FIS from the SCU.
80230557Sjimharris */
81230557Sjimharris#define SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX    0x0FFF
82230557Sjimharris
83230557Sjimharris#define SCU_HARDWARE_SUSPENSION  (0)
84230557Sjimharris#define SCI_SOFTWARE_SUSPENSION  (1)
85230557Sjimharris
86230557Sjimharrisstruct SCIC_SDS_REQUEST;
87230557Sjimharrisstruct SCIC_SDS_REMOTE_DEVICE;
88230557Sjimharrisstruct SCIC_SDS_REMOTE_NODE_CONTEXT;
89230557Sjimharris
90230557Sjimharristypedef void (*SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK)(void *);
91230557Sjimharris
92230557Sjimharristypedef SCI_STATUS (*SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION)(
93230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT    * this_rnc,
94230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
95230557Sjimharris   void                                   * callback_parameter
96230557Sjimharris);
97230557Sjimharris
98230557Sjimharristypedef SCI_STATUS (*SCIC_SDS_REMOTE_NODE_CONTEXT_SUSPEND_OPERATION)(
99230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT    * this_rnc,
100230557Sjimharris   U32                                      suspension_type,
101230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
102230557Sjimharris   void                                   * callback_parameter
103230557Sjimharris);
104230557Sjimharris
105230557Sjimharristypedef SCI_STATUS (* SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST)(
106230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
107230557Sjimharris   struct SCIC_SDS_REQUEST             * the_request
108230557Sjimharris);
109230557Sjimharris
110230557Sjimharristypedef SCI_STATUS (*SCIC_SDS_REMOTE_NODE_CONTEXT_EVENT_HANDLER)(
111230557Sjimharris   struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
112230557Sjimharris   U32                                   event_code
113230557Sjimharris);
114230557Sjimharris
115230557Sjimharris// ---------------------------------------------------------------------------
116230557Sjimharris
117230557Sjimharristypedef struct _SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS
118230557Sjimharris{
119230557Sjimharris   /**
120230557Sjimharris    * This handle is invoked to stop the RNC.  The callback is invoked when after
121230557Sjimharris    * the hardware notification that the RNC has been invalidated.
122230557Sjimharris    */
123230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION destruct_handler;
124230557Sjimharris
125230557Sjimharris   /**
126230557Sjimharris    * This handler is invoked when there is a request to suspend  the RNC.  The
127230557Sjimharris    * callback is invoked after the hardware notification that the remote node is
128230557Sjimharris    * suspended.
129230557Sjimharris    */
130230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_SUSPEND_OPERATION suspend_handler;
131230557Sjimharris
132230557Sjimharris   /**
133230557Sjimharris    * This handler is invoked when there is a request to resume the RNC.  The
134230557Sjimharris    * callback is invoked when after the RNC has reached the ready state.
135230557Sjimharris    */
136230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION resume_handler;
137230557Sjimharris
138230557Sjimharris   /**
139230557Sjimharris    * This handler is invoked when there is a request to start an io request
140230557Sjimharris    * operation.
141230557Sjimharris    */
142230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST start_io_handler;
143230557Sjimharris
144230557Sjimharris   /**
145230557Sjimharris    * This handler is invoked when there is a request to start a task request
146230557Sjimharris    * operation.
147230557Sjimharris    */
148230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST start_task_handler;
149230557Sjimharris
150230557Sjimharris   /**
151230557Sjimharris    * This handler is invoked where there is an RNC event that must be processed.
152230557Sjimharris    */
153230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_EVENT_HANDLER event_handler;
154230557Sjimharris
155230557Sjimharris} SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS;
156230557Sjimharris
157230557Sjimharris// ---------------------------------------------------------------------------
158230557Sjimharris
159230557Sjimharris/**
160230557Sjimharris * @enum
161230557Sjimharris *
162230557Sjimharris * This is the enumeration of the remote node context states.
163230557Sjimharris */
164230557Sjimharristypedef enum _SCIS_SDS_REMOTE_NODE_CONTEXT_STATES
165230557Sjimharris{
166230557Sjimharris   /**
167230557Sjimharris    * This state is the initial state for a remote node context.  On a resume
168230557Sjimharris    * request the remote node context will transition to the posting state.
169230557Sjimharris    */
170230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE,
171230557Sjimharris
172230557Sjimharris   /**
173230557Sjimharris    * This is a transition state that posts the RNi to the hardware. Once the RNC
174230557Sjimharris    * is posted the remote node context will be made ready.
175230557Sjimharris    */
176230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE,
177230557Sjimharris
178230557Sjimharris   /**
179230557Sjimharris    * This is a transition state that will post an RNC invalidate to the
180230557Sjimharris    * hardware.  Once the invalidate is complete the remote node context will
181230557Sjimharris    * transition to the posting state.
182230557Sjimharris    */
183230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE,
184230557Sjimharris
185230557Sjimharris   /**
186230557Sjimharris    * This is a transition state that will post an RNC resume to the hardare.
187230557Sjimharris    * Once the event notification of resume complete is received the remote node
188230557Sjimharris    * context will transition to the ready state.
189230557Sjimharris    */
190230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE,
191230557Sjimharris
192230557Sjimharris   /**
193230557Sjimharris    * This is the state that the remote node context must be in to accept io
194230557Sjimharris    * request operations.
195230557Sjimharris    */
196230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE,
197230557Sjimharris
198230557Sjimharris   /**
199230557Sjimharris    * This is the state that the remote node context transitions to when it gets
200230557Sjimharris    * a TX suspend notification from the hardware.
201230557Sjimharris    */
202230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE,
203230557Sjimharris
204230557Sjimharris   /**
205230557Sjimharris    * This is the state that the remote node context transitions to when it gets
206230557Sjimharris    * a TX RX suspend notification from the hardware.
207230557Sjimharris    */
208230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE,
209230557Sjimharris
210230557Sjimharris   /**
211230557Sjimharris    * This state is a wait state for the remote node context that waits for a
212230557Sjimharris    * suspend notification from the hardware.  This state is entered when either
213230557Sjimharris    * there is a request to supend the remote node context or when there is a TC
214230557Sjimharris    * completion where the remote node will be suspended by the hardware.
215230557Sjimharris    */
216230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE,
217230557Sjimharris
218230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES
219230557Sjimharris
220230557Sjimharris} SCIS_SDS_REMOTE_NODE_CONTEXT_STATES;
221230557Sjimharris
222230557Sjimharris/**
223230557Sjimharris * @enum
224230557Sjimharris *
225230557Sjimharris * This enumeration is used to define the end destination state for the remote
226230557Sjimharris * node context.
227230557Sjimharris */
228230557Sjimharrisenum SCIC_SDS_REMOTE_NODE_CONTEXT_DESTINATION_STATE
229230557Sjimharris{
230230557Sjimharris   SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED,
231230557Sjimharris   SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY,
232230557Sjimharris   SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL
233230557Sjimharris};
234230557Sjimharris
235230557Sjimharris/**
236230557Sjimharris * @struct SCIC_SDS_REMOTE_NODE_CONTEXT
237230557Sjimharris *
238230557Sjimharris * @brief  This structure contains the data associated with the remote
239230557Sjimharris *         node context object.  The remote node context (RNC) object models
240240518Seadler *         the remote device information necessary to manage the
241230557Sjimharris *         silicon RNC.
242230557Sjimharris */
243230557Sjimharristypedef struct SCIC_SDS_REMOTE_NODE_CONTEXT
244230557Sjimharris{
245230557Sjimharris   /**
246230557Sjimharris    * This contains the information used to maintain the loggers for the base
247230557Sjimharris    * state machine.
248230557Sjimharris    */
249230557Sjimharris   SCI_BASE_OBJECT_T parent;
250230557Sjimharris
251230557Sjimharris   /**
252230557Sjimharris    * This pointer simply points to the remote device object containing
253230557Sjimharris    * this RNC.
254230557Sjimharris    *
255230557Sjimharris    * @todo Consider making the device pointer the associated object of the
256230557Sjimharris    *       the parent object.
257230557Sjimharris    */
258230557Sjimharris   struct SCIC_SDS_REMOTE_DEVICE * device;
259230557Sjimharris
260230557Sjimharris   /**
261230557Sjimharris    * This field indicates the remote node index (RNI) associated with
262230557Sjimharris    * this RNC.
263230557Sjimharris    */
264230557Sjimharris   U16 remote_node_index;
265230557Sjimharris
266230557Sjimharris   /**
267230557Sjimharris    * This field is the recored suspension code or the reason for the remote node
268230557Sjimharris    * context suspension.
269230557Sjimharris    */
270230557Sjimharris   U32 suspension_code;
271230557Sjimharris
272230557Sjimharris   /**
273230557Sjimharris    * This field is TRUE if the remote node context is resuming from its current
274230557Sjimharris    * state.  This can cause an automatic resume on receiving a suspension
275230557Sjimharris    * notification.
276230557Sjimharris    */
277230557Sjimharris   enum SCIC_SDS_REMOTE_NODE_CONTEXT_DESTINATION_STATE destination_state;
278230557Sjimharris
279230557Sjimharris   /**
280230557Sjimharris    * This field contains the callback function that the user requested to be
281230557Sjimharris    * called when the requested state transition is complete.
282230557Sjimharris    */
283230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK user_callback;
284230557Sjimharris
285230557Sjimharris   /**
286230557Sjimharris    * This field contains the parameter that is called when the user requested
287230557Sjimharris    * state transition is completed.
288230557Sjimharris    */
289230557Sjimharris   void * user_cookie;
290230557Sjimharris
291230557Sjimharris   /**
292230557Sjimharris    * This field contains the data for the object's state machine.
293230557Sjimharris    */
294230557Sjimharris   SCI_BASE_STATE_MACHINE_T state_machine;
295230557Sjimharris
296230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS * state_handlers;
297230557Sjimharris
298230557Sjimharris   #ifdef SCI_LOGGING
299230557Sjimharris   /**
300230557Sjimharris    * This field conatins the ready substate machine logger.  The logger will
301230557Sjimharris    * emit a message each time the ready substate machine changes state.
302230557Sjimharris    */
303230557Sjimharris   SCI_BASE_STATE_MACHINE_LOGGER_T state_machine_logger;
304230557Sjimharris   #endif
305230557Sjimharris
306230557Sjimharris} SCIC_SDS_REMOTE_NODE_CONTEXT_T;
307230557Sjimharris
308230557Sjimharris// ---------------------------------------------------------------------------
309230557Sjimharris
310230557Sjimharrisextern SCI_BASE_STATE_T
311230557Sjimharris   scic_sds_remote_node_context_state_table[
312230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES];
313230557Sjimharris
314230557Sjimharrisextern SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS
315230557Sjimharris   scic_sds_remote_node_context_state_handler_table[
316230557Sjimharris      SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES];
317230557Sjimharris
318230557Sjimharris// ---------------------------------------------------------------------------
319230557Sjimharris
320230557Sjimharrisvoid scic_sds_remote_node_context_construct(
321230557Sjimharris   struct SCIC_SDS_REMOTE_DEVICE  * device,
322230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc,
323230557Sjimharris   U16                              remote_node_index
324230557Sjimharris);
325230557Sjimharris
326230557Sjimharrisvoid scic_sds_remote_node_context_construct_buffer(
327230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc
328230557Sjimharris);
329230557Sjimharris
330230557SjimharrisBOOL scic_sds_remote_node_context_is_initialized(
331230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc
332230557Sjimharris);
333230557Sjimharris
334230557SjimharrisBOOL scic_sds_remote_node_context_is_ready(
335230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
336230557Sjimharris);
337230557Sjimharris
338230557Sjimharris#define scic_sds_remote_node_context_set_remote_node_index(rnc, rni) \
339230557Sjimharris   ((rnc)->remote_node_index = (rni))
340230557Sjimharris
341230557Sjimharris#define scic_sds_remote_node_context_get_remote_node_index(rcn) \
342230557Sjimharris   ((rnc)->remote_node_index)
343230557Sjimharris
344230557Sjimharris#define scic_sds_remote_node_context_event_handler(rnc, event_code) \
345230557Sjimharris   ((rnc)->state_handlers->event_handler(rnc, event_code))
346230557Sjimharris
347230557Sjimharris#define scic_sds_remote_node_context_resume(rnc, callback, parameter) \
348230557Sjimharris   ((rnc)->state_handlers->resume_handler(rnc, callback, parameter))
349230557Sjimharris
350230557Sjimharris#define scic_sds_remote_node_context_suspend(rnc, suspend_type, callback, parameter) \
351230557Sjimharris    ((rnc)->state_handlers->suspend_handler(rnc, suspend_type, callback, parameter))
352230557Sjimharris
353230557Sjimharris#define scic_sds_remote_node_context_destruct(rnc, callback, parameter) \
354230557Sjimharris    ((rnc)->state_handlers->destruct_handler(rnc, callback, parameter))
355230557Sjimharris
356230557Sjimharris#define scic_sds_remote_node_context_start_io(rnc, request) \
357230557Sjimharris   ((rnc)->state_handlers->start_io_handler(rnc, request))
358230557Sjimharris
359230557Sjimharris#define scic_sds_remote_node_context_start_task(rnc, task) \
360230557Sjimharris   ((rnc)->state_handlers->start_task_handler(rnc, task))
361230557Sjimharris
362230557Sjimharris// ---------------------------------------------------------------------------
363230557Sjimharris
364230557Sjimharris#ifdef SCI_LOGGING
365230557Sjimharrisvoid scic_sds_remote_node_context_initialize_state_logging(
366230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T *this_rnc
367230557Sjimharris);
368230557Sjimharris
369230557Sjimharrisvoid scic_sds_remote_node_context_deinitialize_state_logging(
370230557Sjimharris   SCIC_SDS_REMOTE_NODE_CONTEXT_T *this_rnc
371230557Sjimharris);
372230557Sjimharris#else // SCI_LOGGING
373230557Sjimharris#define scic_sds_remote_node_context_initialize_state_logging(x)
374230557Sjimharris#define scic_sds_remote_node_context_deinitialize_state_logging(x)
375230557Sjimharris#endif // SCI_LOGGING
376230557Sjimharris
377230557Sjimharris#ifdef __cplusplus
378230557Sjimharris}
379230557Sjimharris#endif // __cplusplus
380230557Sjimharris
381230557Sjimharris#endif // _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
382230557Sjimharris
383