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 2003 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * 33 * MODULE: dapl_rsp_create.c 34 * 35 * PURPOSE: Connection management 36 * Description: Interfaces in this file are completely described in 37 * the DAPL 1.1 API, Chapter 6, section 4 38 * 39 * $Id: dapl_rsp_create.c,v 1.14 2003/07/25 19:24:11 sjs2 Exp $ 40 */ 41 42 #include "dapl.h" 43 #include "dapl_sp_util.h" 44 #include "dapl_ia_util.h" 45 #include "dapl_ep_util.h" 46 #include "dapl_adapter_util.h" 47 48 /* 49 * dapl_rsp_create 50 * 51 * uDAPL: User Direct Access Program Library Version 1.1, 6.4.3.4.1 52 * 53 * Create a Resereved Service Point with the specified Endpoint 54 * that generates at most one Connection Request that is 55 * delivered to the specified Event Dispatcher in a notification 56 * event 57 * 58 * Input: 59 * ia_handle 60 * conn_qual 61 * ep_handle 62 * evd_handle 63 * 64 * Output: 65 * rsp_handle 66 * 67 * Returns: 68 * DAT_SUCCESS 69 * DAT_INSUFFICIENT_RESOURCES 70 * DAT_INVALID_PARAMETER 71 * DAT_INVALID_STATE 72 * DAT_CONN_QUAL_IN_USE 73 */ 74 DAT_RETURN 75 dapl_rsp_create( 76 IN DAT_IA_HANDLE ia_handle, 77 IN DAT_CONN_QUAL conn_qual, 78 IN DAT_EP_HANDLE ep_handle, 79 IN DAT_EVD_HANDLE evd_handle, 80 OUT DAT_RSP_HANDLE *rsp_handle) 81 { 82 DAPL_IA *ia_ptr; 83 DAPL_SP *sp_ptr; 84 DAPL_EVD *evd_ptr; 85 DAPL_EP *ep_ptr; 86 DAT_BOOLEAN sp_found; 87 DAT_RETURN dat_status; 88 89 dat_status = DAT_SUCCESS; 90 ia_ptr = (DAPL_IA *)ia_handle; 91 92 dapl_dbg_log(DAPL_DBG_TYPE_CM, 93 ">>> dapl_rsp_free conn_qual: %x EP: %p\n", 94 conn_qual, ep_handle); 95 96 if (DAPL_BAD_HANDLE(ia_ptr, DAPL_MAGIC_IA)) { 97 dat_status = DAT_ERROR(DAT_INVALID_HANDLE, 98 DAT_INVALID_HANDLE_IA); 99 goto bail; 100 } 101 if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP)) { 102 dat_status = DAT_ERROR(DAT_INVALID_HANDLE, 103 DAT_INVALID_HANDLE_EP); 104 goto bail; 105 } 106 if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD)) { 107 dat_status = DAT_ERROR(DAT_INVALID_HANDLE, 108 DAT_INVALID_HANDLE_EVD_CR); 109 goto bail; 110 } 111 112 if (rsp_handle == NULL) { 113 dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5); 114 goto bail; 115 } 116 117 ep_ptr = (DAPL_EP *) ep_handle; 118 if (ep_ptr->param.ep_state != DAT_EP_STATE_UNCONNECTED) { 119 dat_status = DAT_ERROR(DAT_INVALID_STATE, 120 dapls_ep_state_subtype(ep_ptr)); 121 goto bail; 122 } 123 124 evd_ptr = (DAPL_EVD *)evd_handle; 125 if (!(evd_ptr->evd_flags & DAT_EVD_CR_FLAG)) { 126 dat_status = DAT_ERROR(DAT_INVALID_HANDLE, 127 DAT_INVALID_HANDLE_EVD_CR); 128 goto bail; 129 } 130 131 sp_ptr = dapls_ia_sp_search(ia_ptr, conn_qual, DAT_FALSE); 132 sp_found = DAT_TRUE; 133 if (sp_ptr == NULL) { 134 sp_found = DAT_FALSE; 135 136 /* Allocate RSP */ 137 sp_ptr = dapls_sp_alloc(ia_ptr, DAT_FALSE); 138 if (sp_ptr == NULL) { 139 dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 140 DAT_RESOURCE_MEMORY); 141 goto bail; 142 } 143 } 144 145 /* 146 * Fill out the RSP args 147 */ 148 sp_ptr->ia_handle = ia_handle; 149 sp_ptr->conn_qual = conn_qual; 150 sp_ptr->evd_handle = evd_handle; 151 sp_ptr->psp_flags = 0; 152 sp_ptr->ep_handle = ep_handle; 153 154 /* 155 * Take a reference on the EVD handle 156 */ 157 dapl_os_atomic_inc(&((DAPL_EVD *)evd_handle)->evd_ref_count); 158 159 /* 160 * Update the EP state indicating the provider now owns it 161 */ 162 ep_ptr->param.ep_state = DAT_EP_STATE_RESERVED; 163 164 /* 165 * Set up a listener for a connection. Connections can arrive 166 * even before this call returns! 167 */ 168 sp_ptr->state = DAPL_SP_STATE_RSP_LISTENING; 169 sp_ptr->listening = DAT_TRUE; 170 171 if (sp_found == DAT_FALSE) { 172 /* Link it onto the IA */ 173 dapl_ia_link_rsp(ia_ptr, sp_ptr); 174 175 dat_status = dapls_ib_setup_conn_listener(ia_ptr, conn_qual, 176 sp_ptr); 177 178 if (dat_status != DAT_SUCCESS) { 179 /* 180 * Have a problem setting up the connection, something 181 * wrong! 182 * rsp_free will decrement the EVD refcount. Set 183 * listening to * false to avoid tearing down the 184 * conn_listener which didn't * get set up. 185 */ 186 sp_ptr->listening = DAT_FALSE; 187 (void) dapl_rsp_free((DAT_RSP_HANDLE) sp_ptr); 188 189 dapl_dbg_log(DAPL_DBG_TYPE_CM, 190 "--> dapl_rsp_create setup_conn_listener failed: " 191 "%x\n", 192 dat_status); 193 194 goto bail; 195 } 196 } 197 198 /* 199 * Return handle to the user 200 */ 201 *rsp_handle = (DAT_RSP_HANDLE)sp_ptr; 202 203 bail: 204 return (dat_status); 205 } 206