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.
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.
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]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
27 #ifndef _IDM_CONN_SM_H_
28 #define _IDM_CONN_SM_H_
36 * IDM connection state machine events. Most events get generated internally
37 * either by the state machine or by the IDM TX/RX code. For example when IDM
38 * receives a login request for a target connectionit will generate a
39 * CE_LOGIN_RCV event. Similarly when the target sends a successful login
40 * response IDM generate a "CE_LOGIN_SUCCESS_SND" event. The following
41 * events are not detected on the TX/RX path and must be generated explicitly
42 * by the client when appropriate:
44 * CE_LOGOUT_OTHER_CONN_RCV
45 * CE_ASYNC_DROP_CONN_RCV (Only because the message may be received on
46 * a different connection from the connection being dropped)
47 * CE_ASYNC_DROP_ALL_CONN_RCV
48 * CE_LOGOUT_OTHER_CONN_SND
49 * CE_ASYNC_DROP_ALL_CONN_SND
51 * The following events might occur in any state since they are driven
52 * by the PDU's that IDM receives:
55 * CE_LOGIN_SUCCESS_RCV
57 * CE_LOGOUT_SUCCESS_RCV
61 * CE_RX_PROTOCOL_ERROR
64 #define IDM_LOGIN_SECONDS 20
65 #define IDM_LOGOUT_SECONDS 20
66 #define IDM_CLEANUP_SECONDS 0
68 /* Update idm_ce_name table whenever connection events are modified */
72 /* Initiator events */
79 CE_LOGOUT_THIS_CONN_SND
,
80 CE_LOGOUT_OTHER_CONN_SND
,
81 CE_LOGOUT_SESSION_SND
,
82 CE_LOGOUT_SUCCESS_RCV
,
85 CE_ASYNC_DROP_CONN_RCV
,
86 CE_ASYNC_DROP_ALL_CONN_RCV
,
95 CE_LOGIN_FAIL_SND_DONE
,
96 CE_LOGOUT_THIS_CONN_RCV
,
97 CE_LOGOUT_OTHER_CONN_RCV
,
98 CE_LOGOUT_SESSION_RCV
,
99 CE_LOGOUT_SUCCESS_SND
,
100 CE_LOGOUT_SUCCESS_SND_DONE
,
102 CE_LOGOUT_FAIL_SND_DONE
,
105 CE_ASYNC_DROP_CONN_SND
,
106 CE_ASYNC_DROP_ALL_CONN_SND
,
112 CE_TX_PROTOCOL_ERROR
,
114 CE_RX_PROTOCOL_ERROR
,
115 CE_LOGOUT_SESSION_SUCCESS
,
117 CE_CONN_REINSTATE_SUCCESS
,
118 CE_CONN_REINSTATE_FAIL
,
119 CE_ENABLE_DM_SUCCESS
,
122 /* Add new events above CE_MAX_EVENT */
126 #ifdef IDM_CONN_SM_STRINGS
127 /* An array of event text values, for use in logging events */
128 static const char *idm_ce_name
[CE_MAX_EVENT
+1] = {
132 "CE_CONNECT_SUCCESS",
134 "CE_LOGIN_SUCCESS_RCV",
136 "CE_LOGOUT_THIS_CONN_SND",
137 "CE_LOGOUT_OTHER_CONN_SND",
138 "CE_LOGOUT_SESSION_SND",
139 "CE_LOGOUT_SUCCESS_RCV",
140 "CE_LOGOUT_FAIL_RCV",
141 "CE_ASYNC_LOGOUT_RCV",
142 "CE_ASYNC_DROP_CONN_RCV",
143 "CE_ASYNC_DROP_ALL_CONN_RCV",
148 "CE_LOGIN_SUCCESS_SND",
150 "CE_LOGIN_FAIL_SND_DONE",
151 "CE_LOGOUT_THIS_CONN_RCV",
152 "CE_LOGOUT_OTHER_CONN_RCV",
153 "CE_LOGOUT_SESSION_RCV",
154 "CE_LOGOUT_SUCCESS_SND",
155 "CE_LOGOUT_SUCCESS_SND_DONE",
156 "CE_LOGOUT_FAIL_SND",
157 "CE_LOGOUT_FAIL_SND_DONE",
158 "CE_CLEANUP_TIMEOUT",
159 "CE_ASYNC_LOGOUT_SND",
160 "CE_ASYNC_DROP_CONN_SND",
161 "CE_ASYNC_DROP_ALL_CONN_SND",
165 "CE_TX_PROTOCOL_ERROR",
167 "CE_RX_PROTOCOL_ERROR",
168 "CE_LOGOUT_SESSION_SUCCESS",
170 "CE_CONN_REINSTATE_SUCCESS",
171 "CE_CONN_REINSTATE_FAIL",
172 "CE_ENABLE_DM_SUCCESS",
178 /* Update idm_cs_name table whenever connection states are modified */
195 CS_S9B_WAIT_SND_DONE
,
197 /* Add new connection states above CS_MAX_STATE */
201 #ifdef IDM_CONN_SM_STRINGS
202 /* An array of state text values, for use in logging state transitions */
203 static const char *idm_cs_name
[CS_MAX_STATE
+1] = {
218 "CS_S9B_WAIT_SND_DONE",
224 * Currently the state machine has a condition where idm_login_timeout() is
225 * left active after the connection has been closed. This causes the system
226 * to panic when idm_login_timeout() modifies the freed memory. In an attempt
227 * to isolate and find this issue special attention is being placed on
228 * the ic_state_timeout value. After each untimeout call the value will now
229 * be cleared. Just before the value is set the code will check for 0 and
230 * display an error. One final change is being done in idm_conn_sm_fini() which
231 * if ic_state_machine is not 0, an error message will be displayed and
232 * untimeout() called. That should prevent customer sites from seeing the
233 * panic. The code also calls ASSERT(0) which should cause a panic during
236 #define IDM_SM_TIMER_CHECK(ic) \
237 if (ic->ic_state_timeout) { \
238 cmn_err(CE_WARN, "%s: existing timeout still set. " \
239 "state: %s, last: %s\n", __func__, \
240 idm_cs_name[ic->ic_state], \
241 idm_cs_name[ic->ic_last_state]); \
245 #define IDM_SM_TIMER_CLEAR(ic) \
246 (void) untimeout(ic->ic_state_timeout); \
247 ic->ic_state_timeout = 0;
253 } idm_pdu_event_type_t
;
256 CA_TX_PROTOCOL_ERROR
, /* Send "protocol error" to state machine */
257 CA_RX_PROTOCOL_ERROR
, /* Send "protocol error" to state machine */
258 CA_FORWARD
, /* State machine event and forward to client */
259 CA_DROP
/* Drop PDU */
260 } idm_pdu_event_action_t
;
263 struct idm_conn_s
*iec_ic
;
264 idm_conn_event_t iec_event
;
266 idm_pdu_event_type_t iec_pdu_event_type
;
267 boolean_t iec_pdu_forwarded
;
268 } idm_conn_event_ctx_t
;
271 idm_conn_sm_init(struct idm_conn_s
*ic
);
274 idm_conn_sm_fini(struct idm_conn_s
*ic
);
277 idm_notify_client(struct idm_conn_s
*ic
, idm_client_notify_t cn
,
281 idm_conn_event(struct idm_conn_s
*ic
, idm_conn_event_t event
, uintptr_t data
);
284 idm_conn_event(struct idm_conn_s
*ic
, idm_conn_event_t event
, uintptr_t data
);
287 idm_conn_event_locked(struct idm_conn_s
*ic
, idm_conn_event_t event
,
288 uintptr_t event_info
, idm_pdu_event_type_t pdu_event_type
);
291 idm_conn_reinstate_event(struct idm_conn_s
*old_ic
, struct idm_conn_s
*new_ic
);
294 idm_conn_tx_pdu_event(struct idm_conn_s
*ic
, idm_conn_event_t event
,
298 idm_conn_rx_pdu_event(struct idm_conn_s
*ic
, idm_conn_event_t event
,
302 idm_conn_state_str(struct idm_conn_s
*ic
);
308 #endif /* _IDM_CONN_SM_H_ */