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