[DAPL2] DAPL Counters & 2.0.3 extensions to support counter retrieval.
[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     DAPL_CNTR(ia_ptr, DCNT_IA_PSP_CREATE_ANY);  \r
137 \r
138     /*\r
139      * Fill out the args for a PSP\r
140      */\r
141     sp_ptr->evd_handle = evd_handle;\r
142     sp_ptr->psp_flags  = psp_flags;\r
143     sp_ptr->ep_handle  = NULL;\r
144 \r
145     /*\r
146      * Take a reference on the EVD handle\r
147      */\r
148     dapl_os_atomic_inc (& ((DAPL_EVD *)evd_handle)->evd_ref_count);\r
149 \r
150     /* Link it onto the IA */\r
151     dapl_ia_link_psp (ia_ptr, sp_ptr);\r
152 \r
153     /* \r
154      * Set up a listener for a connection. Connections can arrive\r
155      * even before this call returns!\r
156      */\r
157     sp_ptr->state     = DAPL_SP_STATE_PSP_LISTENING;\r
158     sp_ptr->listening = DAT_TRUE;\r
159 \r
160     limit_conn_qual = 0;\r
161     lcl_conn_qual   = hint_conn_qual;\r
162     dat_status      = ~DAT_SUCCESS;\r
163 \r
164     while (dat_status != DAT_SUCCESS)\r
165     { \r
166         dat_status = dapls_ib_setup_conn_listener ( ia_ptr,\r
167                                                     lcl_conn_qual, \r
168                                                     sp_ptr );\r
169 \r
170         lcl_conn_qual++;\r
171 \r
172         if ( dat_status == DAT_CONN_QUAL_IN_USE )\r
173         {\r
174             /*\r
175              * If we have a big number of tries and we still haven't\r
176              * found a service_ID we can use, bail out with an error,\r
177              * something is wrong!\r
178              */\r
179             if ( limit_conn_qual++ > 100000)\r
180             {\r
181                 dat_status = DAT_CONN_QUAL_UNAVAILABLE;\r
182                 break;\r
183             }\r
184         }\r
185     }\r
186     hint_conn_qual = lcl_conn_qual;\r
187 \r
188     if ( dat_status != DAT_SUCCESS )\r
189     {\r
190         /*\r
191          * Have a problem setting up the connection, something wrong!\r
192          */\r
193         dapl_os_atomic_dec (& ((DAPL_EVD *)evd_handle)->evd_ref_count);\r
194         sp_ptr->evd_handle = NULL;\r
195         dapls_ia_unlink_sp ( ia_ptr, sp_ptr );\r
196         dapls_sp_free_sp ( sp_ptr );\r
197 \r
198         dapl_os_printf ("--> dapl_psp_create cannot set up conn listener: %x\n", dat_status);\r
199 \r
200         goto bail;\r
201     }\r
202 \r
203     sp_ptr->conn_qual  = lcl_conn_qual - 1;\r
204 \r
205     /*\r
206      * Return handle to the user\r
207      */\r
208     *conn_qual  = sp_ptr->conn_qual;\r
209     *psp_handle = (DAT_PSP_HANDLE)sp_ptr;\r
210 \r
211  bail:\r
212     return dat_status;\r
213 }\r
214 \r
215 /*\r
216  * Local variables:\r
217  *  c-indent-level: 4\r
218  *  c-basic-offset: 4\r
219  *  c-brace-offset: -4\r
220  *  tab-width: 8\r
221  * End:\r
222  */\r