1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 #ifndef _IDM_CONN_SM_H_
27 #define _IDM_CONN_SM_H_
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33
34 /*
35 * IDM connection state machine events. Most events get generated internally
36 * either by the state machine or by the IDM TX/RX code. For example when IDM
37 * receives a login request for a target connectionit will generate a
38 * CE_LOGIN_RCV event. Similarly when the target sends a successful login
39 * response IDM generate a "CE_LOGIN_SUCCESS_SND" event. The following
40 * events are not detected on the TX/RX path and must be generated explicitly
41 * by the client when appropriate:
42 *
43 * CE_LOGOUT_OTHER_CONN_RCV
44 * CE_ASYNC_DROP_CONN_RCV (Only because the message may be received on
45 * a different connection from the connection being dropped)
46 * CE_ASYNC_DROP_ALL_CONN_RCV
47 * CE_LOGOUT_OTHER_CONN_SND
48 * CE_ASYNC_DROP_ALL_CONN_SND
49 *
50 * The following events might occur in any state since they are driven
51 * by the PDU's that IDM receives:
52 *
53 * CE_LOGIN_RCV
54 * CE_LOGIN_SUCCESS_RCV
55 * CE_LOGIN_FAIL_RCV
56 * CE_LOGOUT_SUCCESS_RCV
57 * CE_LOGOUT_FAIL_RCV
58 * CE_ASYNC_LOGOUT_RCV
59 * CE_MISC_RCV
60 * CE_RX_PROTOCOL_ERROR
61 */
62
63 #define IDM_LOGIN_SECONDS 20
64 #define IDM_LOGOUT_SECONDS 20
65 #define IDM_CLEANUP_SECONDS 0
66
67 /* Update idm_ce_name table whenever connection events are modified */
68 typedef enum {
69 CE_UNDEFINED = 0,
70
71 /* Initiator events */
72 CE_CONNECT_REQ,
73 CE_CONNECT_FAIL,
74 CE_CONNECT_SUCCESS,
75 CE_LOGIN_SND,
76 CE_LOGIN_SUCCESS_RCV,
77 CE_LOGIN_FAIL_RCV,
78 CE_LOGOUT_THIS_CONN_SND,
79 CE_LOGOUT_OTHER_CONN_SND,
80 CE_LOGOUT_SESSION_SND,
81 CE_LOGOUT_SUCCESS_RCV,
82 CE_LOGOUT_FAIL_RCV,
83 CE_ASYNC_LOGOUT_RCV,
84 CE_ASYNC_DROP_CONN_RCV,
85 CE_ASYNC_DROP_ALL_CONN_RCV,
86
87 /* Target events */
88 CE_CONNECT_ACCEPT,
89 CE_CONNECT_REJECT,
90 CE_LOGIN_RCV,
91 CE_LOGIN_TIMEOUT,
92 CE_LOGIN_SUCCESS_SND,
93 CE_LOGIN_FAIL_SND,
94 CE_LOGIN_FAIL_SND_DONE,
95 CE_LOGOUT_THIS_CONN_RCV,
96 CE_LOGOUT_OTHER_CONN_RCV,
97 CE_LOGOUT_SESSION_RCV,
98 CE_LOGOUT_SUCCESS_SND,
99 CE_LOGOUT_SUCCESS_SND_DONE,
100 CE_LOGOUT_FAIL_SND,
101 CE_LOGOUT_FAIL_SND_DONE,
102 CE_CLEANUP_TIMEOUT,
103 CE_ASYNC_LOGOUT_SND,
104 CE_ASYNC_DROP_CONN_SND,
105 CE_ASYNC_DROP_ALL_CONN_SND,
106 CE_LOGOUT_TIMEOUT,
107
108 /* Common events */
109 CE_TRANSPORT_FAIL,
110 CE_MISC_TX,
111 CE_TX_PROTOCOL_ERROR,
112 CE_MISC_RX,
113 CE_RX_PROTOCOL_ERROR,
114 CE_LOGOUT_SESSION_SUCCESS,
115 CE_CONN_REINSTATE,
116 CE_CONN_REINSTATE_SUCCESS,
117 CE_CONN_REINSTATE_FAIL,
118 CE_ENABLE_DM_SUCCESS,
119 CE_ENABLE_DM_FAIL,
120
121 /* Add new events above CE_MAX_EVENT */
122 CE_MAX_EVENT
123 } idm_conn_event_t;
124
125 #ifdef IDM_CONN_SM_STRINGS
126 /* An array of event text values, for use in logging events */
127 static const char *idm_ce_name[CE_MAX_EVENT+1] = {
128 "CE_UNDEFINED",
129 "CE_CONNECT_REQ",
130 "CE_CONNECT_FAIL",
131 "CE_CONNECT_SUCCESS",
132 "CE_LOGIN_SND",
133 "CE_LOGIN_SUCCESS_RCV",
134 "CE_LOGIN_FAIL_RCV",
135 "CE_LOGOUT_THIS_CONN_SND",
136 "CE_LOGOUT_OTHER_CONN_SND",
137 "CE_LOGOUT_SESSION_SND",
138 "CE_LOGOUT_SUCCESS_RCV",
139 "CE_LOGOUT_FAIL_RCV",
140 "CE_ASYNC_LOGOUT_RCV",
141 "CE_ASYNC_DROP_CONN_RCV",
142 "CE_ASYNC_DROP_ALL_CONN_RCV",
143 "CE_CONNECT_ACCEPT",
144 "CE_CONNECT_REJECT",
145 "CE_LOGIN_RCV",
146 "CE_LOGIN_TIMEOUT",
147 "CE_LOGIN_SUCCESS_SND",
148 "CE_LOGIN_FAIL_SND",
149 "CE_LOGIN_FAIL_SND_DONE",
150 "CE_LOGOUT_THIS_CONN_RCV",
151 "CE_LOGOUT_OTHER_CONN_RCV",
152 "CE_LOGOUT_SESSION_RCV",
153 "CE_LOGOUT_SUCCESS_SND",
154 "CE_LOGOUT_SUCCESS_SND_DONE",
155 "CE_LOGOUT_FAIL_SND",
156 "CE_LOGOUT_FAIL_SND_DONE",
157 "CE_CLEANUP_TIMEOUT",
158 "CE_ASYNC_LOGOUT_SND",
159 "CE_ASYNC_DROP_CONN_SND",
160 "CE_ASYNC_DROP_ALL_CONN_SND",
161 "CE_LOGOUT_TIMEOUT",
162 "CE_TRANSPORT_FAIL",
163 "CE_MISC_TX",
164 "CE_TX_PROTOCOL_ERROR",
165 "CE_MISC_RX",
166 "CE_RX_PROTOCOL_ERROR",
167 "CE_LOGOUT_SESSION_SUCCESS",
168 "CE_CONN_REINSTATE",
169 "CE_CONN_REINSTATE_SUCCESS",
170 "CE_CONN_REINSTATE_FAIL",
171 "CE_ENABLE_DM_SUCCESS",
172 "CE_ENABLE_DM_FAIL",
173 "CE_MAX_EVENT"
174 };
175 #endif
176
177 /* Update idm_cs_name table whenever connection states are modified */
178 typedef enum {
179 CS_S0_UNDEFINED = 0,
180
181 CS_S1_FREE,
182 CS_S2_XPT_WAIT,
183 CS_S3_XPT_UP,
184 CS_S4_IN_LOGIN,
185 CS_S5_LOGGED_IN,
186 CS_S6_IN_LOGOUT,
187 CS_S7_LOGOUT_REQ,
188 CS_S8_CLEANUP,
189 CS_S9_INIT_ERROR,
190 CS_S10_IN_CLEANUP,
191 CS_S11_COMPLETE,
192 CS_S12_ENABLE_DM,
193 CS_S9A_REJECTED,
194 CS_S9B_WAIT_SND_DONE,
195
196 /* Add new connection states above CS_MAX_STATE */
197 CS_MAX_STATE
198 } idm_conn_state_t;
199
200 #ifdef IDM_CONN_SM_STRINGS
201 /* An array of state text values, for use in logging state transitions */
202 static const char *idm_cs_name[CS_MAX_STATE+1] = {
203 "CS_S0_UNDEFINED",
204 "CS_S1_FREE",
205 "CS_S2_XPT_WAIT",
206 "CS_S3_XPT_UP",
207 "CS_S4_IN_LOGIN",
208 "CS_S5_LOGGED_IN",
209 "CS_S6_IN_LOGOUT",
210 "CS_S7_LOGOUT_REQ",
211 "CS_S8_CLEANUP",
212 "CS_S9_INIT_ERROR",
213 "CS_S10_IN_CLEANUP",
214 "CS_S11_COMPLETE",
215 "CS_S12_ENABLE_DM",
216 "CS_S9A_REJECTED",
217 "CS_S9B_WAIT_SND_DONE",
218 "CS_MAX_STATE"
219 };
220 #endif
221
222 typedef enum {
223 CT_NONE = 0,
224 CT_RX_PDU,
225 CT_TX_PDU
226 } idm_pdu_event_type_t;
227
228 typedef enum {
229 CA_TX_PROTOCOL_ERROR, /* Send "protocol error" to state machine */
230 CA_RX_PROTOCOL_ERROR, /* Send "protocol error" to state machine */
231 CA_FORWARD, /* State machine event and forward to client */
232 CA_DROP /* Drop PDU */
233 } idm_pdu_event_action_t;
234
235 typedef struct {
236 struct idm_conn_s *iec_ic;
237 idm_conn_event_t iec_event;
238 uintptr_t iec_info;
239 idm_pdu_event_type_t iec_pdu_event_type;
240 boolean_t iec_pdu_forwarded;
241 } idm_conn_event_ctx_t;
242
243 idm_status_t
244 idm_conn_sm_init(struct idm_conn_s *ic);
245
246 void
247 idm_conn_sm_fini(struct idm_conn_s *ic);
248
249 idm_status_t
250 idm_notify_client(struct idm_conn_s *ic, idm_client_notify_t cn,
251 uintptr_t data);
252
253 void
254 idm_conn_event(struct idm_conn_s *ic, idm_conn_event_t event, uintptr_t data);
255
256 void
257 idm_conn_event(struct idm_conn_s *ic, idm_conn_event_t event, uintptr_t data);
258
259 void
260 idm_conn_event_locked(struct idm_conn_s *ic, idm_conn_event_t event,
261 uintptr_t event_info, idm_pdu_event_type_t pdu_event_type);
262
263 idm_status_t
264 idm_conn_reinstate_event(struct idm_conn_s *old_ic, struct idm_conn_s *new_ic);
265
266 void
267 idm_conn_tx_pdu_event(struct idm_conn_s *ic, idm_conn_event_t event,
268 uintptr_t data);
269
270 void
271 idm_conn_rx_pdu_event(struct idm_conn_s *ic, idm_conn_event_t event,
272 uintptr_t data);
273
274 char *
275 idm_conn_state_str(struct idm_conn_s *ic);
276
277 #ifdef __cplusplus
278 }
279 #endif
280
281 #endif /* _IDM_CONN_SM_H_ */