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 (c) 2002-2003, Network Appliance, Inc. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * 33 * MODULE: dapl_evd_connection_callback.c 34 * 35 * PURPOSE: implements connection callbacks 36 * 37 * Description: Accepts asynchronous callbacks from the Communications Manager 38 * for EVDs that have been specified as the connection_evd. 39 * 40 * $Id: dapl_evd_connection_callb.c,v 1.33 2003/07/30 18:13:38 hobie16 Exp $ 41 */ 42 43 #include "dapl.h" 44 #include "dapl_evd_util.h" 45 #include "dapl_ep_util.h" 46 47 48 /* 49 * dapl_evd_connection_callback 50 * 51 * Connection callback function for ACTIVE connection requests; callbacks 52 * generated by the Connection Manager in response to issuing a 53 * connect call. 54 * 55 * Input: 56 * ib_cm_handle, 57 * ib_cm_event 58 * private_data_ptr 59 * context (evd) 60 * cr_pp 61 * 62 * Output: 63 * None 64 * 65 */ 66 67 void 68 dapl_evd_connection_callback( 69 IN ib_cm_handle_t ib_cm_handle, 70 IN const ib_cm_events_t ib_cm_event, 71 IN const void *private_data_ptr, 72 IN const void *context) 73 { 74 DAPL_EP *ep_ptr; 75 DAPL_EVD *evd_ptr; 76 DAPL_PRIVATE *prd_ptr; 77 DAT_EVENT_NUMBER event_type; 78 79 dapl_dbg_log( 80 DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, 81 "--> dapl_evd_connection_callback: ctxt: %p event: %x" 82 " cm_handle %p\n", 83 context, 84 ib_cm_event, 85 ib_cm_handle); 86 87 /* 88 * Determine the type of handle passed back to us in the context 89 * and sort out key parameters. 90 */ 91 dapl_os_assert(((DAPL_HEADER *)context)->magic == DAPL_MAGIC_EP || 92 ((DAPL_HEADER *)context)->magic == DAPL_MAGIC_EP_EXIT); 93 /* 94 * Active side of the connection, context is an EP and 95 * PSP is irrelevant. 96 */ 97 ep_ptr = (DAPL_EP *)context; 98 evd_ptr = (DAPL_EVD *)ep_ptr->param.connect_evd_handle; 99 100 prd_ptr = (DAPL_PRIVATE *)private_data_ptr; 101 102 switch (ib_cm_event) { 103 case IB_CME_CONNECTED: 104 { 105 /* 106 * If we don't have an EP at this point we are very screwed 107 * up 108 */ 109 DAT_RETURN dat_status; 110 111 if (ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING) { 112 /* 113 * If someone pulled the plug on the connection, just 114 * exit 115 */ 116 break; 117 } 118 dapls_ib_connected(ep_ptr); 119 ep_ptr->param.ep_state = DAT_EP_STATE_CONNECTED; 120 ep_ptr->cm_handle = ib_cm_handle; 121 /* copy in the private data */ 122 (void) dapl_os_memcpy(ep_ptr->private_data, 123 prd_ptr->private_data, 124 IB_MAX_REQ_PDATA_SIZE); 125 126 dat_status = dapls_evd_post_connection_event( 127 evd_ptr, 128 DAT_CONNECTION_EVENT_ESTABLISHED, 129 (DAT_HANDLE) ep_ptr, 130 IB_MAX_REQ_PDATA_SIZE, 131 ep_ptr->private_data); 132 133 if (dat_status != DAT_SUCCESS) { 134 (void) dapls_ib_disconnect(ep_ptr, 135 DAT_CLOSE_ABRUPT_FLAG); 136 ep_ptr->param.ep_state = 137 DAT_EP_STATE_DISCONNECT_PENDING; 138 } 139 140 /* 141 * If we received any premature DTO completions and 142 * post them to the recv evd now. 143 * there is a race here - if events arrive after we change 144 * the ep state to connected and before we process premature 145 * events 146 */ 147 dapls_evd_post_premature_events(ep_ptr); 148 149 break; 150 } 151 case IB_CME_DISCONNECTED: 152 case IB_CME_DISCONNECTED_ON_LINK_DOWN: 153 { 154 /* 155 * EP is now fully disconnected; initiate any post processing 156 * to reset the underlying QP and get the EP ready for 157 * another connection 158 */ 159 if (ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED) { 160 /* DTO error caused this */ 161 event_type = DAT_CONNECTION_EVENT_BROKEN; 162 } else { 163 ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED; 164 dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, 165 ib_cm_event); 166 event_type = DAT_CONNECTION_EVENT_DISCONNECTED; 167 } 168 169 /* If the EP has been freed, the evd_ptr will be NULL */ 170 if (evd_ptr != NULL) { 171 (void) dapls_evd_post_connection_event( 172 evd_ptr, event_type, (DAT_HANDLE) ep_ptr, 0, 0); 173 } 174 175 /* 176 * If the user has done an ep_free of the EP, we have been 177 * waiting for the disconnect event; just clean it up now. 178 */ 179 if (ep_ptr->header.magic == DAPL_MAGIC_EP_EXIT) { 180 (void) dapl_ep_free(ep_ptr); 181 } 182 break; 183 } 184 case IB_CME_DESTINATION_REJECT_PRIVATE_DATA: 185 { 186 ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED; 187 dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event); 188 (void) dapls_evd_post_connection_event( 189 evd_ptr, 190 DAT_CONNECTION_EVENT_PEER_REJECTED, 191 (DAT_HANDLE) ep_ptr, 192 0, 193 0); 194 break; 195 } 196 case IB_CME_DESTINATION_UNREACHABLE: 197 { 198 ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED; 199 dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event); 200 (void) dapls_evd_post_connection_event( 201 evd_ptr, 202 DAT_CONNECTION_EVENT_UNREACHABLE, 203 (DAT_HANDLE) ep_ptr, 204 0, 205 0); 206 break; 207 } 208 case IB_CME_DESTINATION_REJECT: 209 case IB_CME_TOO_MANY_CONNECTION_REQUESTS: 210 case IB_CME_LOCAL_FAILURE: 211 { 212 ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED; 213 dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event); 214 (void) dapls_evd_post_connection_event( 215 evd_ptr, 216 DAT_CONNECTION_EVENT_NON_PEER_REJECTED, 217 (DAT_HANDLE) ep_ptr, 218 0, 219 0); 220 break; 221 } 222 case IB_CME_TIMED_OUT: 223 { 224 ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED; 225 dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event); 226 (void) dapls_evd_post_connection_event( 227 evd_ptr, 228 DAT_CONNECTION_EVENT_TIMED_OUT, 229 (DAT_HANDLE) ep_ptr, 230 0, 231 0); 232 break; 233 } 234 case IB_CME_CONNECTION_REQUEST_PENDING: 235 case IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA: 236 default: 237 { 238 dapl_os_assert(0); /* shouldn't happen */ 239 break; 240 } 241 } 242 243 dapl_dbg_log(DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK, 244 "dapl_evd_connection_callback () returns\n"); 245 246 } 247 248 249 /* 250 * Local variables: 251 * c-indent-level: 4 252 * c-basic-offset: 4 253 * tab-width: 8 254 * End: 255 */ 256