1*9e39c5baSBill Taylor /*
2*9e39c5baSBill Taylor  * CDDL HEADER START
3*9e39c5baSBill Taylor  *
4*9e39c5baSBill Taylor  * The contents of this file are subject to the terms of the
5*9e39c5baSBill Taylor  * Common Development and Distribution License (the "License").
6*9e39c5baSBill Taylor  * You may not use this file except in compliance with the License.
7*9e39c5baSBill Taylor  *
8*9e39c5baSBill Taylor  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9e39c5baSBill Taylor  * or http://www.opensolaris.org/os/licensing.
10*9e39c5baSBill Taylor  * See the License for the specific language governing permissions
11*9e39c5baSBill Taylor  * and limitations under the License.
12*9e39c5baSBill Taylor  *
13*9e39c5baSBill Taylor  * When distributing Covered Code, include this CDDL HEADER in each
14*9e39c5baSBill Taylor  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9e39c5baSBill Taylor  * If applicable, add the following below this CDDL HEADER, with the
16*9e39c5baSBill Taylor  * fields enclosed by brackets "[]" replaced with your own identifying
17*9e39c5baSBill Taylor  * information: Portions Copyright [yyyy] [name of copyright owner]
18*9e39c5baSBill Taylor  *
19*9e39c5baSBill Taylor  * CDDL HEADER END
20*9e39c5baSBill Taylor  */
21*9e39c5baSBill Taylor 
22*9e39c5baSBill Taylor /*
23*9e39c5baSBill Taylor  * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
24*9e39c5baSBill Taylor  */
25*9e39c5baSBill Taylor 
26*9e39c5baSBill Taylor /*
27*9e39c5baSBill Taylor  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
28*9e39c5baSBill Taylor  * Use is subject to license terms.
29*9e39c5baSBill Taylor  */
30*9e39c5baSBill Taylor 
31*9e39c5baSBill Taylor /*
32*9e39c5baSBill Taylor  *
33*9e39c5baSBill Taylor  * MODULE: dapl_ep_connect.c
34*9e39c5baSBill Taylor  *
35*9e39c5baSBill Taylor  * PURPOSE: Endpoint management
36*9e39c5baSBill Taylor  * Description: Interfaces in this file are completely described in
37*9e39c5baSBill Taylor  *		the DAPL 1.1 API, Chapter 6, section 5
38*9e39c5baSBill Taylor  *
39*9e39c5baSBill Taylor  * $Id: dapl_ep_connect.c,v 1.23 2003/07/31 13:55:18 hobie16 Exp $
40*9e39c5baSBill Taylor  */
41*9e39c5baSBill Taylor 
42*9e39c5baSBill Taylor #include "dapl.h"
43*9e39c5baSBill Taylor #include "dapl_ep_util.h"
44*9e39c5baSBill Taylor #include "dapl_adapter_util.h"
45*9e39c5baSBill Taylor #include "dapl_evd_util.h"
46*9e39c5baSBill Taylor 
47*9e39c5baSBill Taylor /*
48*9e39c5baSBill Taylor  * dapl_ep_connect
49*9e39c5baSBill Taylor  *
50*9e39c5baSBill Taylor  * DAPL Requirements Version xxx, 6.5.7
51*9e39c5baSBill Taylor  *
52*9e39c5baSBill Taylor  * Request a connection be established between the local Endpoint
53*9e39c5baSBill Taylor  * and a remote Endpoint. This operation is used by the active/client
54*9e39c5baSBill Taylor  * side of a connection
55*9e39c5baSBill Taylor  *
56*9e39c5baSBill Taylor  * Input:
57*9e39c5baSBill Taylor  *	ep_handle
58*9e39c5baSBill Taylor  *	remote_ia_address
59*9e39c5baSBill Taylor  *	remote_conn_qual
60*9e39c5baSBill Taylor  *	timeout
61*9e39c5baSBill Taylor  *	private_data_size
62*9e39c5baSBill Taylor  *	privaet_data
63*9e39c5baSBill Taylor  *	qos
64*9e39c5baSBill Taylor  *	connect_flags
65*9e39c5baSBill Taylor  *
66*9e39c5baSBill Taylor  * Output:
67*9e39c5baSBill Taylor  *	None
68*9e39c5baSBill Taylor  *
69*9e39c5baSBill Taylor  * Returns:
70*9e39c5baSBill Taylor  *	DAT_SUCCESS
71*9e39c5baSBill Taylor  *	DAT_INSUFFICIENT_RESOUCRES
72*9e39c5baSBill Taylor  *	DAT_INVALID_PARAMETER
73*9e39c5baSBill Taylor  *	DAT_MODLE_NOT_SUPPORTED
74*9e39c5baSBill Taylor  */
75*9e39c5baSBill Taylor DAT_RETURN
dapl_ep_connect(IN DAT_EP_HANDLE ep_handle,IN DAT_IA_ADDRESS_PTR remote_ia_address,IN DAT_CONN_QUAL remote_conn_qual,IN DAT_TIMEOUT timeout,IN DAT_COUNT private_data_size,IN const DAT_PVOID private_data,IN DAT_QOS qos,IN DAT_CONNECT_FLAGS connect_flags)76*9e39c5baSBill Taylor dapl_ep_connect(
77*9e39c5baSBill Taylor 	IN DAT_EP_HANDLE ep_handle,
78*9e39c5baSBill Taylor 	IN DAT_IA_ADDRESS_PTR remote_ia_address,
79*9e39c5baSBill Taylor 	IN DAT_CONN_QUAL remote_conn_qual,
80*9e39c5baSBill Taylor 	IN DAT_TIMEOUT timeout,
81*9e39c5baSBill Taylor 	IN DAT_COUNT private_data_size,
82*9e39c5baSBill Taylor 	IN const DAT_PVOID private_data,
83*9e39c5baSBill Taylor 	IN DAT_QOS qos,
84*9e39c5baSBill Taylor 	IN DAT_CONNECT_FLAGS connect_flags)
85*9e39c5baSBill Taylor {
86*9e39c5baSBill Taylor 	DAPL_EP *ep_ptr;
87*9e39c5baSBill Taylor 	DAPL_PRIVATE prd;
88*9e39c5baSBill Taylor 	DAPL_EP	alloc_ep;
89*9e39c5baSBill Taylor 	DAT_RETURN dat_status;
90*9e39c5baSBill Taylor 
91*9e39c5baSBill Taylor 	dapl_dbg_log(DAPL_DBG_TYPE_API | DAPL_DBG_TYPE_CM,
92*9e39c5baSBill Taylor 	    "dapl_ep_connect (%p, {%u.%u.%u.%u}, %X, %d, %d, %p, %x, %x)\n",
93*9e39c5baSBill Taylor 	    ep_handle,
94*9e39c5baSBill Taylor 	    remote_ia_address->sa_data[2],
95*9e39c5baSBill Taylor 	    remote_ia_address->sa_data[3],
96*9e39c5baSBill Taylor 	    remote_ia_address->sa_data[4],
97*9e39c5baSBill Taylor 	    remote_ia_address->sa_data[5],
98*9e39c5baSBill Taylor 	    remote_conn_qual,
99*9e39c5baSBill Taylor 	    timeout,
100*9e39c5baSBill Taylor 	    private_data_size,
101*9e39c5baSBill Taylor 	    private_data,
102*9e39c5baSBill Taylor 	    qos,
103*9e39c5baSBill Taylor 	    connect_flags);
104*9e39c5baSBill Taylor 
105*9e39c5baSBill Taylor 	dat_status = DAT_SUCCESS;
106*9e39c5baSBill Taylor 	ep_ptr = (DAPL_EP *) ep_handle;
107*9e39c5baSBill Taylor 
108*9e39c5baSBill Taylor 	/*
109*9e39c5baSBill Taylor 	 * Verify parameter & state. The connection handle must be good
110*9e39c5baSBill Taylor 	 * at this point.
111*9e39c5baSBill Taylor 	 */
112*9e39c5baSBill Taylor 	if (DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP)) {
113*9e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
114*9e39c5baSBill Taylor 		    DAT_INVALID_HANDLE_EP);
115*9e39c5baSBill Taylor 		goto bail;
116*9e39c5baSBill Taylor 	}
117*9e39c5baSBill Taylor 
118*9e39c5baSBill Taylor 	if (DAPL_BAD_HANDLE(ep_ptr->param.connect_evd_handle, DAPL_MAGIC_EVD)) {
119*9e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
120*9e39c5baSBill Taylor 		    DAT_INVALID_HANDLE_EVD_CONN);
121*9e39c5baSBill Taylor 		goto bail;
122*9e39c5baSBill Taylor 	}
123*9e39c5baSBill Taylor 
124*9e39c5baSBill Taylor 	/*
125*9e39c5baSBill Taylor 	 * If the endpoint needs a QP, associated the QP with it.
126*9e39c5baSBill Taylor 	 * This needs to be done carefully, in order to:
127*9e39c5baSBill Taylor 	 *	* Avoid allocating under a lock.
128*9e39c5baSBill Taylor 	 *  * Not step on data structures being altered by
129*9e39c5baSBill Taylor 	 *    routines with which we are racing.
130*9e39c5baSBill Taylor 	 * So we:
131*9e39c5baSBill Taylor 	 *  * Confirm that a new QP is needed and is not forbidden by the
132*9e39c5baSBill Taylor 	 *    current state.
133*9e39c5baSBill Taylor 	 *  * Allocate it into a separate EP.
134*9e39c5baSBill Taylor 	 *  * Take the EP lock.
135*9e39c5baSBill Taylor 	 *  * Reconfirm that the EP is in a state where it needs a QP.
136*9e39c5baSBill Taylor 	 *  * Assign the QP and release the lock.
137*9e39c5baSBill Taylor 	 */
138*9e39c5baSBill Taylor 	if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {
139*9e39c5baSBill Taylor 		if (ep_ptr->param.pz_handle == NULL ||
140*9e39c5baSBill Taylor 		    DAPL_BAD_HANDLE(ep_ptr->param.pz_handle, DAPL_MAGIC_PZ)) {
141*9e39c5baSBill Taylor 			dat_status = DAT_ERROR(DAT_INVALID_STATE,
142*9e39c5baSBill Taylor 			    DAT_INVALID_STATE_EP_NOTREADY);
143*9e39c5baSBill Taylor 			goto bail;
144*9e39c5baSBill Taylor 		}
145*9e39c5baSBill Taylor 		alloc_ep = *ep_ptr;
146*9e39c5baSBill Taylor 
147*9e39c5baSBill Taylor 		dat_status = dapls_ib_qp_alloc(ep_ptr->header.owner_ia,
148*9e39c5baSBill Taylor 		    &alloc_ep, ep_ptr);
149*9e39c5baSBill Taylor 		if (dat_status != DAT_SUCCESS) {
150*9e39c5baSBill Taylor 			dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
151*9e39c5baSBill Taylor 			    DAT_RESOURCE_MEMORY);
152*9e39c5baSBill Taylor 			goto bail;
153*9e39c5baSBill Taylor 		}
154*9e39c5baSBill Taylor 
155*9e39c5baSBill Taylor 		dapl_os_lock(&ep_ptr->header.lock);
156*9e39c5baSBill Taylor 		/*
157*9e39c5baSBill Taylor 		 * PZ shouldn't have changed since we're only racing with
158*9e39c5baSBill Taylor 		 * dapl_cr_accept()
159*9e39c5baSBill Taylor 		 */
160*9e39c5baSBill Taylor 		if (ep_ptr->qp_state != DAPL_QP_STATE_UNATTACHED) {
161*9e39c5baSBill Taylor 			/* Bail, cleaning up.  */
162*9e39c5baSBill Taylor 			dapl_os_unlock(&ep_ptr->header.lock);
163*9e39c5baSBill Taylor 			dat_status = dapls_ib_qp_free(ep_ptr->header.owner_ia,
164*9e39c5baSBill Taylor 			    &alloc_ep);
165*9e39c5baSBill Taylor 			if (dat_status != DAT_SUCCESS) {
166*9e39c5baSBill Taylor 				dapl_dbg_log(DAPL_DBG_TYPE_WARN,
167*9e39c5baSBill Taylor 				    "ep_connect: ib_qp_free failed with %x\n",
168*9e39c5baSBill Taylor 				    dat_status);
169*9e39c5baSBill Taylor 			}
170*9e39c5baSBill Taylor 			dat_status = DAT_ERROR(DAT_INVALID_STATE,
171*9e39c5baSBill Taylor 			    dapls_ep_state_subtype(ep_ptr));
172*9e39c5baSBill Taylor 			goto bail;
173*9e39c5baSBill Taylor 		}
174*9e39c5baSBill Taylor 		ep_ptr->qp_handle = alloc_ep.qp_handle;
175*9e39c5baSBill Taylor 		ep_ptr->qpn = alloc_ep.qpn;
176*9e39c5baSBill Taylor 		ep_ptr->qp_state = alloc_ep.qp_state;
177*9e39c5baSBill Taylor 
178*9e39c5baSBill Taylor 		dapl_os_unlock(&ep_ptr->header.lock);
179*9e39c5baSBill Taylor 	}
180*9e39c5baSBill Taylor 
181*9e39c5baSBill Taylor 	/*
182*9e39c5baSBill Taylor 	 * We do state checks and transitions under lock.
183*9e39c5baSBill Taylor 	 * The only code we're racing against is dapl_cr_accept.
184*9e39c5baSBill Taylor 	 */
185*9e39c5baSBill Taylor 	dapl_os_lock(&ep_ptr->header.lock);
186*9e39c5baSBill Taylor 
187*9e39c5baSBill Taylor 	/*
188*9e39c5baSBill Taylor 	 * Verify the attributes of the EP handle before we connect it. Test
189*9e39c5baSBill Taylor 	 * all of the handles to make sure they are currently valid.
190*9e39c5baSBill Taylor 	 * Specifically:
191*9e39c5baSBill Taylor 	 *   pz_handle		required
192*9e39c5baSBill Taylor 	 *   recv_evd_handle	optional, but must be valid
193*9e39c5baSBill Taylor 	 *   request_evd_handle	optional, but must be valid
194*9e39c5baSBill Taylor 	 *   connect_evd_handle	required
195*9e39c5baSBill Taylor 	 */
196*9e39c5baSBill Taylor 	if (ep_ptr->param.pz_handle == NULL ||
197*9e39c5baSBill Taylor 	    DAPL_BAD_HANDLE(ep_ptr->param.pz_handle, DAPL_MAGIC_PZ) ||
198*9e39c5baSBill Taylor 	    ep_ptr->param.connect_evd_handle == NULL ||
199*9e39c5baSBill Taylor 	    DAPL_BAD_HANDLE(ep_ptr->param.connect_evd_handle,
200*9e39c5baSBill Taylor 	    DAPL_MAGIC_EVD) ||
201*9e39c5baSBill Taylor 	    !(((DAPL_EVD *)ep_ptr->param.connect_evd_handle)->evd_flags &
202*9e39c5baSBill Taylor 	    DAT_EVD_CONNECTION_FLAG) ||
203*9e39c5baSBill Taylor 	    (ep_ptr->param.recv_evd_handle != DAT_HANDLE_NULL &&
204*9e39c5baSBill Taylor 	    (DAPL_BAD_HANDLE(ep_ptr->param.recv_evd_handle,
205*9e39c5baSBill Taylor 	    DAPL_MAGIC_EVD))) ||
206*9e39c5baSBill Taylor 	    (ep_ptr->param.request_evd_handle != DAT_HANDLE_NULL &&
207*9e39c5baSBill Taylor 	    (DAPL_BAD_HANDLE(ep_ptr->param.request_evd_handle,
208*9e39c5baSBill Taylor 	    DAPL_MAGIC_EVD)))) {
209*9e39c5baSBill Taylor 		dapl_os_unlock(&ep_ptr->header.lock);
210*9e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_STATE,
211*9e39c5baSBill Taylor 		    DAT_INVALID_STATE_EP_NOTREADY);
212*9e39c5baSBill Taylor 		goto bail;
213*9e39c5baSBill Taylor 	}
214*9e39c5baSBill Taylor 
215*9e39c5baSBill Taylor 	/*
216*9e39c5baSBill Taylor 	 * Check both the EP state and the QP state: if we don't have a QP
217*9e39c5baSBill Taylor 	 *  we need to attach one now.
218*9e39c5baSBill Taylor 	 */
219*9e39c5baSBill Taylor 	if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {
220*9e39c5baSBill Taylor 		dat_status = dapls_ib_qp_alloc(ep_ptr->header.owner_ia,
221*9e39c5baSBill Taylor 		    ep_ptr, ep_ptr);
222*9e39c5baSBill Taylor 
223*9e39c5baSBill Taylor 		if (dat_status != DAT_SUCCESS) {
224*9e39c5baSBill Taylor 			dapl_os_unlock(&ep_ptr->header.lock);
225*9e39c5baSBill Taylor 			dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
226*9e39c5baSBill Taylor 			    DAT_RESOURCE_TEP);
227*9e39c5baSBill Taylor 			goto bail;
228*9e39c5baSBill Taylor 		}
229*9e39c5baSBill Taylor 	}
230*9e39c5baSBill Taylor 
231*9e39c5baSBill Taylor 	if (ep_ptr->param.ep_state != DAT_EP_STATE_UNCONNECTED) {
232*9e39c5baSBill Taylor 		dapl_os_unlock(&ep_ptr->header.lock);
233*9e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_STATE,
234*9e39c5baSBill Taylor 		    dapls_ep_state_subtype(ep_ptr));
235*9e39c5baSBill Taylor 		goto bail;
236*9e39c5baSBill Taylor 	}
237*9e39c5baSBill Taylor 
238*9e39c5baSBill Taylor 	if (qos != DAT_QOS_BEST_EFFORT ||
239*9e39c5baSBill Taylor 	    connect_flags != DAT_CONNECT_DEFAULT_FLAG) {
240*9e39c5baSBill Taylor 		/*
241*9e39c5baSBill Taylor 		 * At this point we only support one QOS level
242*9e39c5baSBill Taylor 		 */
243*9e39c5baSBill Taylor 		dapl_os_unlock(&ep_ptr->header.lock);
244*9e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_MODEL_NOT_SUPPORTED, 0);
245*9e39c5baSBill Taylor 		goto bail;
246*9e39c5baSBill Taylor 	}
247*9e39c5baSBill Taylor 
248*9e39c5baSBill Taylor 	/*
249*9e39c5baSBill Taylor 	 * Verify the private data size doesn't exceed the max
250*9e39c5baSBill Taylor 	 */
251*9e39c5baSBill Taylor 	if (private_data_size > DAPL_CONSUMER_MAX_PRIVATE_DATA_SIZE) {
252*9e39c5baSBill Taylor 		dapl_os_unlock(&ep_ptr->header.lock);
253*9e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
254*9e39c5baSBill Taylor 		goto bail;
255*9e39c5baSBill Taylor 	}
256*9e39c5baSBill Taylor 
257*9e39c5baSBill Taylor 	/*
258*9e39c5baSBill Taylor 	 * transition the state before requesting a connection to avoid
259*9e39c5baSBill Taylor 	 * race conditions
260*9e39c5baSBill Taylor 	 */
261*9e39c5baSBill Taylor 	ep_ptr->param.ep_state = DAT_EP_STATE_ACTIVE_CONNECTION_PENDING;
262*9e39c5baSBill Taylor 
263*9e39c5baSBill Taylor 	/*
264*9e39c5baSBill Taylor 	 * At this point we're committed, and done with the endpoint
265*9e39c5baSBill Taylor 	 * except for the connect, so we can drop the lock.
266*9e39c5baSBill Taylor 	 */
267*9e39c5baSBill Taylor 	dapl_os_unlock(&ep_ptr->header.lock);
268*9e39c5baSBill Taylor 
269*9e39c5baSBill Taylor 	/*
270*9e39c5baSBill Taylor 	 * fill in the private data
271*9e39c5baSBill Taylor 	 */
272*9e39c5baSBill Taylor 	(void) dapl_os_memzero(&prd, sizeof (DAPL_PRIVATE));
273*9e39c5baSBill Taylor 	if (private_data_size > 0)
274*9e39c5baSBill Taylor 		(void) dapl_os_memcpy(prd.private_data, private_data,
275*9e39c5baSBill Taylor 		    private_data_size);
276*9e39c5baSBill Taylor 
277*9e39c5baSBill Taylor 	/* Copy the connection qualifiers */
278*9e39c5baSBill Taylor 	(void) dapl_os_memcpy(ep_ptr->param.remote_ia_address_ptr,
279*9e39c5baSBill Taylor 	    remote_ia_address, sizeof (DAT_SOCK_ADDR6));
280*9e39c5baSBill Taylor 	ep_ptr->param.remote_port_qual = remote_conn_qual;
281*9e39c5baSBill Taylor 
282*9e39c5baSBill Taylor 	dat_status = dapls_ib_connect(ep_handle,
283*9e39c5baSBill Taylor 	    remote_ia_address, remote_conn_qual,
284*9e39c5baSBill Taylor 	    private_data_size, &prd, timeout);
285*9e39c5baSBill Taylor 
286*9e39c5baSBill Taylor 	if (dat_status != DAT_SUCCESS) {
287*9e39c5baSBill Taylor 		DAPL_EVD	*evd_ptr;
288*9e39c5baSBill Taylor 
289*9e39c5baSBill Taylor 		if (dat_status == DAT_ERROR(DAT_INVALID_ADDRESS,
290*9e39c5baSBill Taylor 		    DAT_INVALID_ADDRESS_UNREACHABLE)) {
291*9e39c5baSBill Taylor 			/* Unreachable IP address */
292*9e39c5baSBill Taylor 			evd_ptr = (DAPL_EVD *)ep_ptr->param.connect_evd_handle;
293*9e39c5baSBill Taylor 			if (evd_ptr != NULL) {
294*9e39c5baSBill Taylor 				(void) dapls_evd_post_connection_event(evd_ptr,
295*9e39c5baSBill Taylor 				    DAT_CONNECTION_EVENT_UNREACHABLE,
296*9e39c5baSBill Taylor 				    (DAT_HANDLE) ep_ptr, 0, 0);
297*9e39c5baSBill Taylor 			}
298*9e39c5baSBill Taylor 			ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
299*9e39c5baSBill Taylor 			dat_status = DAT_SUCCESS;
300*9e39c5baSBill Taylor 		} else if (dat_status == DAT_ERROR(DAT_INVALID_PARAMETER,
301*9e39c5baSBill Taylor 		    DAT_INVALID_ADDRESS_UNREACHABLE)) {
302*9e39c5baSBill Taylor 			/* Non-existant connection qualifier */
303*9e39c5baSBill Taylor 			evd_ptr = (DAPL_EVD *)ep_ptr->param.connect_evd_handle;
304*9e39c5baSBill Taylor 			if (evd_ptr != NULL) {
305*9e39c5baSBill Taylor 				(void) dapls_evd_post_connection_event(evd_ptr,
306*9e39c5baSBill Taylor 				    DAT_CONNECTION_EVENT_NON_PEER_REJECTED,
307*9e39c5baSBill Taylor 				    (DAT_HANDLE) ep_ptr, 0, 0);
308*9e39c5baSBill Taylor 			}
309*9e39c5baSBill Taylor 			ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
310*9e39c5baSBill Taylor 			dat_status = DAT_SUCCESS;
311*9e39c5baSBill Taylor 		} else {
312*9e39c5baSBill Taylor 			ep_ptr->param.ep_state = DAT_EP_STATE_UNCONNECTED;
313*9e39c5baSBill Taylor 		}
314*9e39c5baSBill Taylor 	}
315*9e39c5baSBill Taylor 
316*9e39c5baSBill Taylor bail:
317*9e39c5baSBill Taylor 	dapl_dbg_log(DAPL_DBG_TYPE_RTN | DAPL_DBG_TYPE_CM,
318*9e39c5baSBill Taylor 	    "dapl_ep_connect () returns 0x%x\n", dat_status);
319*9e39c5baSBill Taylor 
320*9e39c5baSBill Taylor 	return (dat_status);
321*9e39c5baSBill Taylor }
322