1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3  *
4  * This file is provided under a dual BSD/GPLv2 license.  When using or
5  * redistributing this file, you may do so under either license.
6  *
7  * GPL LICENSE SUMMARY
8  *
9  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of version 2 of the GNU General Public License as
13  * published by the Free Software Foundation.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23  * The full GNU General Public License is included in this distribution
24  * in the file called LICENSE.GPL.
25  *
26  * BSD LICENSE
27  *
28  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29  * All rights reserved.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
34  *
35  *   * Redistributions of source code must retain the above copyright
36  *     notice, this list of conditions and the following disclaimer.
37  *   * Redistributions in binary form must reproduce the above copyright
38  *     notice, this list of conditions and the following disclaimer in
39  *     the documentation and/or other materials provided with the
40  *     distribution.
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53  *
54  * $FreeBSD$
55  */
56 #ifndef _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
57 #define _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
58 
59 /**
60  * @file
61  *
62  * @brief This file contains the structures, constants, and prototypes
63  *        associated with the remote node context in the silicon.  It
64  *        exists to model and manage the remote node context in the silicon.
65  */
66 
67 #ifdef __cplusplus
68 extern "C" {
69 #endif // __cplusplus
70 
71 #include <dev/isci/scil/sci_types.h>
72 #include <dev/isci/scil/sci_base_state.h>
73 #include <dev/isci/scil/sci_base_state_machine.h>
74 #include <dev/isci/scil/sci_base_state_machine_logger.h>
75 
76 // ---------------------------------------------------------------------------
77 
78 /**
79  * This constant represents an invalid remote device id, it is used to program
80  * the STPDARNI register so the driver knows when it has received a SIGNATURE
81  * FIS from the SCU.
82  */
83 #define SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX    0x0FFF
84 
85 #define SCU_HARDWARE_SUSPENSION  (0)
86 #define SCI_SOFTWARE_SUSPENSION  (1)
87 
88 struct SCIC_SDS_REQUEST;
89 struct SCIC_SDS_REMOTE_DEVICE;
90 struct SCIC_SDS_REMOTE_NODE_CONTEXT;
91 
92 typedef void (*SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK)(void *);
93 
94 typedef SCI_STATUS (*SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION)(
95    struct SCIC_SDS_REMOTE_NODE_CONTEXT    * this_rnc,
96    SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
97    void                                   * callback_parameter
98 );
99 
100 typedef SCI_STATUS (*SCIC_SDS_REMOTE_NODE_CONTEXT_SUSPEND_OPERATION)(
101    struct SCIC_SDS_REMOTE_NODE_CONTEXT    * this_rnc,
102    U32                                      suspension_type,
103    SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK   the_callback,
104    void                                   * callback_parameter
105 );
106 
107 typedef SCI_STATUS (* SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST)(
108    struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
109    struct SCIC_SDS_REQUEST             * the_request
110 );
111 
112 typedef SCI_STATUS (*SCIC_SDS_REMOTE_NODE_CONTEXT_EVENT_HANDLER)(
113    struct SCIC_SDS_REMOTE_NODE_CONTEXT * this_rnc,
114    U32                                   event_code
115 );
116 
117 // ---------------------------------------------------------------------------
118 
119 typedef struct _SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS
120 {
121    /**
122     * This handle is invoked to stop the RNC.  The callback is invoked when after
123     * the hardware notification that the RNC has been invalidated.
124     */
125    SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION destruct_handler;
126 
127    /**
128     * This handler is invoked when there is a request to suspend  the RNC.  The
129     * callback is invoked after the hardware notification that the remote node is
130     * suspended.
131     */
132    SCIC_SDS_REMOTE_NODE_CONTEXT_SUSPEND_OPERATION suspend_handler;
133 
134    /**
135     * This handler is invoked when there is a request to resume the RNC.  The
136     * callback is invoked when after the RNC has reached the ready state.
137     */
138    SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION resume_handler;
139 
140    /**
141     * This handler is invoked when there is a request to start an io request
142     * operation.
143     */
144    SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST start_io_handler;
145 
146    /**
147     * This handler is invoked when there is a request to start a task request
148     * operation.
149     */
150    SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST start_task_handler;
151 
152    /**
153     * This handler is invoked where there is an RNC event that must be processed.
154     */
155    SCIC_SDS_REMOTE_NODE_CONTEXT_EVENT_HANDLER event_handler;
156 
157 } SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS;
158 
159 // ---------------------------------------------------------------------------
160 
161 /**
162  * @enum
163  *
164  * This is the enumeration of the remote node context states.
165  */
166 typedef enum _SCIS_SDS_REMOTE_NODE_CONTEXT_STATES
167 {
168    /**
169     * This state is the initial state for a remote node context.  On a resume
170     * request the remote node context will transition to the posting state.
171     */
172    SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE,
173 
174    /**
175     * This is a transition state that posts the RNi to the hardware. Once the RNC
176     * is posted the remote node context will be made ready.
177     */
178    SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE,
179 
180    /**
181     * This is a transition state that will post an RNC invalidate to the
182     * hardware.  Once the invalidate is complete the remote node context will
183     * transition to the posting state.
184     */
185    SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE,
186 
187    /**
188     * This is a transition state that will post an RNC resume to the hardare.
189     * Once the event notification of resume complete is received the remote node
190     * context will transition to the ready state.
191     */
192    SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE,
193 
194    /**
195     * This is the state that the remote node context must be in to accept io
196     * request operations.
197     */
198    SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE,
199 
200    /**
201     * This is the state that the remote node context transitions to when it gets
202     * a TX suspend notification from the hardware.
203     */
204    SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE,
205 
206    /**
207     * This is the state that the remote node context transitions to when it gets
208     * a TX RX suspend notification from the hardware.
209     */
210    SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE,
211 
212    /**
213     * This state is a wait state for the remote node context that waits for a
214     * suspend notification from the hardware.  This state is entered when either
215     * there is a request to supend the remote node context or when there is a TC
216     * completion where the remote node will be suspended by the hardware.
217     */
218    SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE,
219 
220    SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES
221 
222 } SCIS_SDS_REMOTE_NODE_CONTEXT_STATES;
223 
224 /**
225  * @enum
226  *
227  * This enumeration is used to define the end destination state for the remote
228  * node context.
229  */
230 enum SCIC_SDS_REMOTE_NODE_CONTEXT_DESTINATION_STATE
231 {
232    SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED,
233    SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY,
234    SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL
235 };
236 
237 /**
238  * @struct SCIC_SDS_REMOTE_NODE_CONTEXT
239  *
240  * @brief  This structure contains the data associated with the remote
241  *         node context object.  The remote node context (RNC) object models
242  *         the remote device information necessary to manage the
243  *         silicon RNC.
244  */
245 typedef struct SCIC_SDS_REMOTE_NODE_CONTEXT
246 {
247    /**
248     * This contains the information used to maintain the loggers for the base
249     * state machine.
250     */
251    SCI_BASE_OBJECT_T parent;
252 
253    /**
254     * This pointer simply points to the remote device object containing
255     * this RNC.
256     *
257     * @todo Consider making the device pointer the associated object of the
258     *       the parent object.
259     */
260    struct SCIC_SDS_REMOTE_DEVICE * device;
261 
262    /**
263     * This field indicates the remote node index (RNI) associated with
264     * this RNC.
265     */
266    U16 remote_node_index;
267 
268    /**
269     * This field is the recorded suspension code or the reason for the remote node
270     * context suspension.
271     */
272    U32 suspension_code;
273 
274    /**
275     * This field is TRUE if the remote node context is resuming from its current
276     * state.  This can cause an automatic resume on receiving a suspension
277     * notification.
278     */
279    enum SCIC_SDS_REMOTE_NODE_CONTEXT_DESTINATION_STATE destination_state;
280 
281    /**
282     * This field contains the callback function that the user requested to be
283     * called when the requested state transition is complete.
284     */
285    SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK user_callback;
286 
287    /**
288     * This field contains the parameter that is called when the user requested
289     * state transition is completed.
290     */
291    void * user_cookie;
292 
293    /**
294     * This field contains the data for the object's state machine.
295     */
296    SCI_BASE_STATE_MACHINE_T state_machine;
297 
298    SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS * state_handlers;
299 
300    #ifdef SCI_LOGGING
301    /**
302     * This field conatins the ready substate machine logger.  The logger will
303     * emit a message each time the ready substate machine changes state.
304     */
305    SCI_BASE_STATE_MACHINE_LOGGER_T state_machine_logger;
306    #endif
307 
308 } SCIC_SDS_REMOTE_NODE_CONTEXT_T;
309 
310 // ---------------------------------------------------------------------------
311 
312 extern SCI_BASE_STATE_T
313    scic_sds_remote_node_context_state_table[
314       SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES];
315 
316 extern SCIC_SDS_REMOTE_NODE_CONTEXT_HANDLERS
317    scic_sds_remote_node_context_state_handler_table[
318       SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES];
319 
320 // ---------------------------------------------------------------------------
321 
322 void scic_sds_remote_node_context_construct(
323    struct SCIC_SDS_REMOTE_DEVICE  * device,
324    SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc,
325    U16                              remote_node_index
326 );
327 
328 void scic_sds_remote_node_context_construct_buffer(
329    SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc
330 );
331 
332 BOOL scic_sds_remote_node_context_is_initialized(
333    SCIC_SDS_REMOTE_NODE_CONTEXT_T * rnc
334 );
335 
336 BOOL scic_sds_remote_node_context_is_ready(
337    SCIC_SDS_REMOTE_NODE_CONTEXT_T * this_rnc
338 );
339 
340 #define scic_sds_remote_node_context_set_remote_node_index(rnc, rni) \
341    ((rnc)->remote_node_index = (rni))
342 
343 #define scic_sds_remote_node_context_get_remote_node_index(rcn) \
344    ((rnc)->remote_node_index)
345 
346 #define scic_sds_remote_node_context_event_handler(rnc, event_code) \
347    ((rnc)->state_handlers->event_handler(rnc, event_code))
348 
349 #define scic_sds_remote_node_context_resume(rnc, callback, parameter) \
350    ((rnc)->state_handlers->resume_handler(rnc, callback, parameter))
351 
352 #define scic_sds_remote_node_context_suspend(rnc, suspend_type, callback, parameter) \
353     ((rnc)->state_handlers->suspend_handler(rnc, suspend_type, callback, parameter))
354 
355 #define scic_sds_remote_node_context_destruct(rnc, callback, parameter) \
356     ((rnc)->state_handlers->destruct_handler(rnc, callback, parameter))
357 
358 #define scic_sds_remote_node_context_start_io(rnc, request) \
359    ((rnc)->state_handlers->start_io_handler(rnc, request))
360 
361 #define scic_sds_remote_node_context_start_task(rnc, task) \
362    ((rnc)->state_handlers->start_task_handler(rnc, task))
363 
364 // ---------------------------------------------------------------------------
365 
366 #ifdef SCI_LOGGING
367 void scic_sds_remote_node_context_initialize_state_logging(
368    SCIC_SDS_REMOTE_NODE_CONTEXT_T *this_rnc
369 );
370 
371 void scic_sds_remote_node_context_deinitialize_state_logging(
372    SCIC_SDS_REMOTE_NODE_CONTEXT_T *this_rnc
373 );
374 #else // SCI_LOGGING
375 #define scic_sds_remote_node_context_initialize_state_logging(x)
376 #define scic_sds_remote_node_context_deinitialize_state_logging(x)
377 #endif // SCI_LOGGING
378 
379 #ifdef __cplusplus
380 }
381 #endif // __cplusplus
382 
383 #endif // _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
384 
385