git-svn-id: svn://openib.tc.cornell.edu/gen1/branches/WOF2-0@1528 ad392aa1-c5ef-ae45...
[mirror/winof/.git] / ulp / dapl2 / dapl / common / dapl_psp_create_any.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_psp_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_adapter_util.h"\r
43 \r
44 /*\r
45  * dapl_psp_create_any\r
46  *\r
47  * uDAPL: User Direct Access Program Library Version 1.1, 6.4.3.3\r
48  *\r
49  * Create a persistent Public Service Point that can receive multiple\r
50  * requests for connections and generate multiple connection request\r
51  * instances that will be delivered to the specified Event Dispatcher\r
52  * in a notification event. Differs from dapl_psp_create() in that\r
53  * the conn_qual is selected by the implementation and returned to\r
54  * the user.\r
55  *\r
56  * Input:\r
57  *      ia_handle\r
58  *      evd_handle\r
59  *      psp_flags\r
60  *\r
61  * Output:\r
62  *      conn_qual\r
63  *      psp_handle\r
64  *\r
65  * Returns:\r
66  *      DAT_SUCCESS\r
67  *      DAT_INSUFFICIENT_RESOURCES\r
68  *      DAT_INVALID_HANDLE\r
69  *      DAT_INVALID_PARAMETER\r
70  *      DAT_CONN_QUAL_IN_USE\r
71  *      DAT_MODEL_NOT_SUPPORTED\r
72  */\r
73 DAT_RETURN DAT_API\r
74 dapl_psp_create_any (\r
75         IN      DAT_IA_HANDLE      ia_handle,\r
76         OUT     DAT_CONN_QUAL      *conn_qual,\r
77         IN      DAT_EVD_HANDLE     evd_handle,\r
78         IN      DAT_PSP_FLAGS      psp_flags,\r
79         OUT     DAT_PSP_HANDLE     *psp_handle )\r
80 {\r
81     DAPL_IA             *ia_ptr;\r
82     DAPL_SP             *sp_ptr;\r
83     DAPL_EVD            *evd_ptr;\r
84     DAT_RETURN          dat_status;\r
85     static DAT_CONN_QUAL hint_conn_qual = 1024; /* seed value */\r
86     DAT_CONN_QUAL       lcl_conn_qual;\r
87     DAT_CONN_QUAL       limit_conn_qual;\r
88 \r
89     ia_ptr = (DAPL_IA *)ia_handle;\r
90     dat_status = DAT_SUCCESS;\r
91 \r
92     if ( DAPL_BAD_HANDLE (ia_ptr, DAPL_MAGIC_IA))\r
93     {\r
94         dat_status = DAT_ERROR (DAT_INVALID_HANDLE,DAT_INVALID_HANDLE_IA);\r
95         goto bail;\r
96     }\r
97     if (DAPL_BAD_HANDLE (evd_handle, DAPL_MAGIC_EVD))\r
98     {\r
99         dat_status = DAT_ERROR (DAT_INVALID_HANDLE,DAT_INVALID_HANDLE_EVD_CR);\r
100         goto bail;\r
101     }\r
102 \r
103     if ( psp_handle == NULL )\r
104     {\r
105         dat_status = DAT_ERROR (DAT_INVALID_PARAMETER,DAT_INVALID_ARG5);\r
106         goto bail;\r
107     }\r
108     if (conn_qual == NULL)\r
109     {\r
110         dat_status = DAT_ERROR (DAT_INVALID_PARAMETER,DAT_INVALID_ARG2);\r
111         goto bail;\r
112     }\r
113 \r
114     evd_ptr = (DAPL_EVD *)evd_handle;\r
115     if ( ! (evd_ptr->evd_flags & DAT_EVD_CR_FLAG) )\r
116     {\r
117         dat_status = DAT_ERROR (DAT_INVALID_HANDLE,DAT_INVALID_HANDLE_EVD_CR);\r
118         goto bail;\r
119     }\r
120 \r
121     if (psp_flags != DAT_PSP_CONSUMER_FLAG &&\r
122         psp_flags != DAT_PSP_PROVIDER_FLAG)\r
123     {\r
124         dat_status = DAT_ERROR (DAT_INVALID_PARAMETER,DAT_INVALID_ARG4);\r
125         goto bail;\r
126     }\r
127         \r
128     /* Allocate PSP */\r
129     sp_ptr = dapls_sp_alloc ( ia_ptr, DAT_TRUE );\r
130     if ( sp_ptr == NULL )\r
131     {\r
132         dat_status = DAT_ERROR (DAT_INSUFFICIENT_RESOURCES,DAT_RESOURCE_MEMORY);\r
133         goto bail;\r
134     }\r
135 \r
136     /*\r
137      * Fill out the args for a PSP\r
138      */\r
139     sp_ptr->evd_handle = evd_handle;\r
140     sp_ptr->psp_flags  = psp_flags;\r
141     sp_ptr->ep_handle  = NULL;\r
142 \r
143     /*\r
144      * Take a reference on the EVD handle\r
145      */\r
146     dapl_os_atomic_inc (& ((DAPL_EVD *)evd_handle)->evd_ref_count);\r
147 \r
148     /* Link it onto the IA */\r
149     dapl_ia_link_psp (ia_ptr, sp_ptr);\r
150 \r
151     /* \r
152      * Set up a listener for a connection. Connections can arrive\r
153      * even before this call returns!\r
154      */\r
155     sp_ptr->state     = DAPL_SP_STATE_PSP_LISTENING;\r
156     sp_ptr->listening = DAT_TRUE;\r
157 \r
158     limit_conn_qual = 0;\r
159     lcl_conn_qual   = hint_conn_qual;\r
160     dat_status      = ~DAT_SUCCESS;\r
161 \r
162     while (dat_status != DAT_SUCCESS)\r
163     { \r
164         dat_status = dapls_ib_setup_conn_listener ( ia_ptr,\r
165                                                     lcl_conn_qual, \r
166                                                     sp_ptr );\r
167 \r
168         lcl_conn_qual++;\r
169 \r
170         if ( dat_status == DAT_CONN_QUAL_IN_USE )\r
171         {\r
172             /*\r
173              * If we have a big number of tries and we still haven't\r
174              * found a service_ID we can use, bail out with an error,\r
175              * something is wrong!\r
176              */\r
177             if ( limit_conn_qual++ > 100000)\r
178             {\r
179                 dat_status = DAT_CONN_QUAL_UNAVAILABLE;\r
180                 break;\r
181             }\r
182         }\r
183     }\r
184     hint_conn_qual = lcl_conn_qual;\r
185 \r
186     if ( dat_status != DAT_SUCCESS )\r
187     {\r
188         /*\r
189          * Have a problem setting up the connection, something wrong!\r
190          */\r
191         dapl_os_atomic_dec (& ((DAPL_EVD *)evd_handle)->evd_ref_count);\r
192         sp_ptr->evd_handle = NULL;\r
193         dapls_ia_unlink_sp ( ia_ptr, sp_ptr );\r
194         dapls_sp_free_sp ( sp_ptr );\r
195 \r
196         dapl_os_printf ("--> dapl_psp_create cannot set up conn listener: %x\n", dat_status);\r
197 \r
198         goto bail;\r
199     }\r
200 \r
201     sp_ptr->conn_qual  = lcl_conn_qual - 1;\r
202 \r
203     /*\r
204      * Return handle to the user\r
205      */\r
206     *conn_qual  = sp_ptr->conn_qual;\r
207     *psp_handle = (DAT_PSP_HANDLE)sp_ptr;\r
208 \r
209  bail:\r
210     return dat_status;\r
211 }\r
212 \r
213 /*\r
214  * Local variables:\r
215  *  c-indent-level: 4\r
216  *  c-basic-offset: 4\r
217  *  c-brace-offset: -4\r
218  *  tab-width: 8\r
219  * End:\r
220  */\r