[DAPL2] DAPL Counters & 2.0.3 extensions to support counter retrieval.
[mirror/winof/.git] / ulp / dapl2 / dapl / common / dapl_rsp_create.c
1 /*\r
2  * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.\r
3  *\r
4  * This Software is licensed under one of the following licenses:\r
5  *\r
6  * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
7  *    available from the Open Source Initiative, see\r
8  *    http://www.opensource.org/licenses/cpl.php.\r
9  *\r
10  * 2) under the terms of the "The BSD License" a copy of which is\r
11  *    available from the Open Source Initiative, see\r
12  *    http://www.opensource.org/licenses/bsd-license.php.\r
13  *\r
14  * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
15  *    copy of which is available from the Open Source Initiative, see\r
16  *    http://www.opensource.org/licenses/gpl-license.php.\r
17  *\r
18  * Licensee has the right to choose one of the above licenses.\r
19  *\r
20  * Redistributions of source code must retain the above copyright\r
21  * notice and one of the license notices.\r
22  *\r
23  * Redistributions in binary form must reproduce both the above copyright\r
24  * notice, one of the license notices in the documentation\r
25  * and/or other materials provided with the distribution.\r
26  */\r
27 \r
28 /**********************************************************************\r
29  * \r
30  * MODULE: dapl_rsp_create.c\r
31  *\r
32  * PURPOSE: Connection management\r
33  * Description: Interfaces in this file are completely described in\r
34  *              the DAPL 1.1 API, Chapter 6, section 4\r
35  *\r
36  * $Id:$\r
37  **********************************************************************/\r
38 \r
39 #include "dapl.h"\r
40 #include "dapl_sp_util.h"\r
41 #include "dapl_ia_util.h"\r
42 #include "dapl_ep_util.h"\r
43 #include "dapl_adapter_util.h"\r
44 \r
45 /*\r
46  * dapl_rsp_create\r
47  *\r
48  * uDAPL: User Direct Access Program Library Version 1.1, 6.4.3.4.1\r
49  *\r
50  * Create a Resereved Service Point with the specified Endpoint\r
51  * that generates at most one Connection Request that is\r
52  * delivered to the specified Event Dispatcher in a notification\r
53  * event\r
54  *\r
55  * Input:\r
56  *      ia_handle\r
57  *      conn_qual\r
58  *      ep_handle\r
59  *      evd_handle\r
60  *\r
61  * Output:\r
62  *      rsp_handle\r
63  *\r
64  * Returns:\r
65  *      DAT_SUCCESS\r
66  *      DAT_INSUFFICIENT_RESOURCES\r
67  *      DAT_INVALID_PARAMETER\r
68  *      DAT_INVALID_STATE\r
69  *      DAT_CONN_QUAL_IN_USE\r
70  */\r
71 DAT_RETURN DAT_API\r
72 dapl_rsp_create (\r
73         IN      DAT_IA_HANDLE      ia_handle,\r
74         IN      DAT_CONN_QUAL      conn_qual,\r
75         IN      DAT_EP_HANDLE      ep_handle,\r
76         IN      DAT_EVD_HANDLE     evd_handle,\r
77         OUT     DAT_RSP_HANDLE     *rsp_handle )\r
78 {\r
79     DAPL_IA             *ia_ptr;\r
80     DAPL_SP             *sp_ptr;\r
81     DAPL_EVD            *evd_ptr;\r
82     DAPL_EP             *ep_ptr;\r
83     DAT_BOOLEAN         sp_found;\r
84     DAT_RETURN          dat_status;\r
85 \r
86     dat_status = DAT_SUCCESS;\r
87     ia_ptr = (DAPL_IA *)ia_handle;\r
88 \r
89     dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
90                   ">>> dapl_rsp_free conn_qual: %x EP: %p\n", \r
91                   conn_qual, ep_handle);\r
92 \r
93     if ( DAPL_BAD_HANDLE (ia_ptr, DAPL_MAGIC_IA) )\r
94     {\r
95         dat_status = DAT_ERROR (DAT_INVALID_HANDLE,DAT_INVALID_HANDLE_IA);\r
96         goto bail;\r
97     }\r
98     if ( DAPL_BAD_HANDLE (ep_handle, DAPL_MAGIC_EP) )\r
99     {\r
100         dat_status = DAT_ERROR (DAT_INVALID_HANDLE,DAT_INVALID_HANDLE_EP);\r
101         goto bail;\r
102     }\r
103     if ( DAPL_BAD_HANDLE (evd_handle, DAPL_MAGIC_EVD) )\r
104     {\r
105         dat_status = DAT_ERROR (DAT_INVALID_HANDLE,DAT_INVALID_HANDLE_EVD_CR);\r
106         goto bail;\r
107     }\r
108 \r
109     if ( rsp_handle == NULL )\r
110     {\r
111         dat_status = DAT_ERROR (DAT_INVALID_PARAMETER,DAT_INVALID_ARG5);\r
112         goto bail;\r
113     }\r
114 \r
115     ep_ptr = (DAPL_EP *) ep_handle;\r
116     if ( ep_ptr->param.ep_state != DAT_EP_STATE_UNCONNECTED )\r
117     {\r
118         dat_status = DAT_ERROR (DAT_INVALID_STATE,dapls_ep_state_subtype (ep_ptr));\r
119         goto bail;\r
120     }\r
121 \r
122     evd_ptr = (DAPL_EVD *)evd_handle;\r
123     if ( ! (evd_ptr->evd_flags & DAT_EVD_CR_FLAG) )\r
124     {\r
125         dat_status = DAT_ERROR (DAT_INVALID_HANDLE,DAT_INVALID_HANDLE_EVD_CR);\r
126         goto bail;\r
127     }\r
128 \r
129     DAPL_CNTR(ia_ptr, DCNT_IA_RSP_CREATE);      \r
130 \r
131     sp_ptr = dapls_ia_sp_search (ia_ptr, conn_qual, DAT_FALSE);\r
132     sp_found = DAT_TRUE;\r
133     if (sp_ptr == NULL)\r
134     {\r
135         sp_found = DAT_FALSE;\r
136 \r
137         /* Allocate RSP */\r
138         sp_ptr = dapls_sp_alloc ( ia_ptr, DAT_FALSE );\r
139         if ( sp_ptr == NULL )\r
140         {\r
141             dat_status = \r
142                 DAT_ERROR (DAT_INSUFFICIENT_RESOURCES,DAT_RESOURCE_MEMORY);\r
143             goto bail;\r
144         }\r
145     }\r
146 \r
147     /*\r
148      * Fill out the RSP args\r
149      */\r
150     sp_ptr->conn_qual  = conn_qual;\r
151     sp_ptr->evd_handle = evd_handle;\r
152     sp_ptr->psp_flags  = 0;\r
153     sp_ptr->ep_handle  = ep_handle;\r
154 \r
155     /*\r
156      * Take a reference on the EVD handle\r
157      */\r
158     dapl_os_atomic_inc (& ((DAPL_EVD *)evd_handle)->evd_ref_count);\r
159 \r
160     /*\r
161      * Update the EP state indicating the provider now owns it\r
162      */\r
163     ep_ptr->param.ep_state = DAT_EP_STATE_RESERVED;\r
164 \r
165     /* \r
166      * Set up a listener for a connection. Connections can arrive\r
167      * even before this call returns!\r
168      */\r
169     sp_ptr->state     = DAPL_SP_STATE_RSP_LISTENING;\r
170     sp_ptr->listening = DAT_TRUE;\r
171 \r
172     if (sp_found == DAT_FALSE)\r
173     {\r
174         /* Link it onto the IA */\r
175         dapl_ia_link_rsp (ia_ptr, sp_ptr);\r
176 \r
177         dat_status = dapls_ib_setup_conn_listener ( ia_ptr,\r
178                                                     conn_qual, \r
179                                                     sp_ptr );\r
180 \r
181         if ( dat_status != DAT_SUCCESS )\r
182         {\r
183             /*\r
184              * Have a problem setting up the connection, something\r
185              * wrong!  Decrements the EVD refcount & release it. Set \r
186              * the state to FREE, so we know the call failed.\r
187              */\r
188             dapl_os_atomic_dec (& ((DAPL_EVD *)evd_handle)->evd_ref_count);\r
189             sp_ptr->evd_handle = NULL;\r
190             sp_ptr->state      = DAPL_SP_STATE_FREE;\r
191             dapls_ia_unlink_sp (ia_ptr, sp_ptr);\r
192             dapls_sp_free_sp (sp_ptr);\r
193 \r
194             dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
195                       "--> dapl_rsp_create setup_conn_listener failed: %x\n", \r
196                       dat_status);\r
197 \r
198             goto bail;\r
199         }\r
200     }\r
201 \r
202     /*\r
203      * Return handle to the user\r
204      */\r
205     *rsp_handle = (DAT_RSP_HANDLE)sp_ptr;\r
206 \r
207  bail:\r
208     return dat_status;\r
209 }\r
210 \r
211 /*\r
212  * Local variables:\r
213  *  c-indent-level: 4\r
214  *  c-basic-offset: 4\r
215  *  c-brace-offset: -4\r
216  *  tab-width: 8\r
217  * End:\r
218  */\r
219 \r
220 \r