[DAPL2] DAPL Counters & 2.0.3 extensions to support counter retrieval.
[mirror/winof/.git] / ulp / dapl2 / dapl / common / dapl_psp_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_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\r
46  *\r
47  * uDAPL: User Direct Access Program Library Version 1.1, 6.4.1.1\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.\r
53  *\r
54  * Input:\r
55  *      ia_handle\r
56  *      conn_qual\r
57  *      evd_handle\r
58  *      psp_flags\r
59  *\r
60  * Output:\r
61  *      psp_handle\r
62  *\r
63  * Returns:\r
64  *      DAT_SUCCESS\r
65  *      DAT_INSUFFICIENT_RESOURCES\r
66  *      DAT_INVALID_PARAMETER\r
67  *      DAT_CONN_QUAL_IN_USE\r
68  *      DAT_MODEL_NOT_SUPPORTED\r
69  */\r
70 DAT_RETURN DAT_API\r
71 dapl_psp_create (\r
72         IN      DAT_IA_HANDLE      ia_handle,\r
73         IN      DAT_CONN_QUAL      conn_qual,\r
74         IN      DAT_EVD_HANDLE     evd_handle,\r
75         IN      DAT_PSP_FLAGS      psp_flags,\r
76         OUT     DAT_PSP_HANDLE     *psp_handle )\r
77 {\r
78     DAPL_IA             *ia_ptr;\r
79     DAPL_SP             *sp_ptr;\r
80     DAPL_EVD            *evd_ptr;\r
81     DAT_BOOLEAN         sp_found;\r
82     DAT_RETURN          dat_status;\r
83 \r
84     ia_ptr = (DAPL_IA *)ia_handle;\r
85     dat_status = DAT_SUCCESS;\r
86 \r
87     if ( DAPL_BAD_HANDLE (ia_ptr, DAPL_MAGIC_IA))\r
88     {\r
89         dat_status = DAT_ERROR (DAT_INVALID_HANDLE,DAT_INVALID_HANDLE_IA);\r
90         goto bail;\r
91     }\r
92     if (DAPL_BAD_HANDLE (evd_handle, DAPL_MAGIC_EVD))\r
93     {\r
94         dat_status = DAT_ERROR (DAT_INVALID_HANDLE,DAT_INVALID_HANDLE_EVD_CR);\r
95         goto bail;\r
96     }\r
97 \r
98     if ( psp_handle == NULL )\r
99     {\r
100         dat_status = DAT_ERROR (DAT_INVALID_PARAMETER,DAT_INVALID_ARG5);\r
101         goto bail;\r
102     }\r
103 \r
104     evd_ptr = (DAPL_EVD *)evd_handle;\r
105     if ( ! (evd_ptr->evd_flags & DAT_EVD_CR_FLAG) )\r
106     {\r
107         dat_status = DAT_ERROR (DAT_INVALID_HANDLE,DAT_INVALID_HANDLE_EVD_CR);\r
108         goto bail;\r
109     }\r
110 \r
111     if (psp_flags != DAT_PSP_CONSUMER_FLAG &&\r
112         psp_flags != DAT_PSP_PROVIDER_FLAG)\r
113     {\r
114         dat_status = DAT_ERROR (DAT_INVALID_PARAMETER,DAT_INVALID_ARG4);\r
115         goto bail;\r
116     }\r
117 \r
118     DAPL_CNTR(ia_ptr, DCNT_IA_PSP_CREATE);      \r
119 \r
120     /*\r
121      * See if we have a quiescent listener to use for this PSP, else\r
122      * create one and set it listening\r
123      */\r
124     sp_ptr = dapls_ia_sp_search (ia_ptr, conn_qual, DAT_TRUE);\r
125     sp_found = DAT_TRUE;\r
126     if (sp_ptr == NULL)\r
127     {\r
128         /* Allocate PSP */\r
129         sp_found = DAT_FALSE;\r
130         sp_ptr   = dapls_sp_alloc ( ia_ptr, DAT_TRUE );\r
131         if ( sp_ptr == NULL )\r
132         {\r
133             dat_status = \r
134                 DAT_ERROR (DAT_INSUFFICIENT_RESOURCES,DAT_RESOURCE_MEMORY);\r
135             goto bail;\r
136         }\r
137     }\r
138     else if (sp_ptr->listening == DAT_TRUE)\r
139     {\r
140         dat_status = DAT_ERROR (DAT_CONN_QUAL_IN_USE, 0);\r
141         goto bail;\r
142     }\r
143 \r
144     /*\r
145      * Fill out the args for a PSP\r
146      */\r
147     sp_ptr->conn_qual  = conn_qual;\r
148     sp_ptr->evd_handle = evd_handle;\r
149     sp_ptr->psp_flags  = psp_flags;\r
150     sp_ptr->ep_handle  = NULL;\r
151 \r
152     /*\r
153      * Take a reference on the EVD handle\r
154      */\r
155     dapl_os_atomic_inc (& ((DAPL_EVD *)evd_handle)->evd_ref_count);\r
156 \r
157     /* \r
158      * Set up a listener for a connection. Connections can arrive\r
159      * even before this call returns!\r
160      */\r
161     sp_ptr->state     = DAPL_SP_STATE_PSP_LISTENING;\r
162     sp_ptr->listening = DAT_TRUE;\r
163 \r
164     /*\r
165      * If this is a new sp we need to add it to the IA queue, and set up\r
166      * a conn_listener.\r
167      */\r
168     if (sp_found == DAT_FALSE)\r
169     {\r
170         /* Link it onto the IA before enabling it to receive conn\r
171          * requests\r
172          */\r
173         dapl_ia_link_psp (ia_ptr, sp_ptr);\r
174 \r
175         dat_status = dapls_ib_setup_conn_listener ( ia_ptr,\r
176                                                     conn_qual, \r
177                                                     sp_ptr );\r
178 \r
179         if ( dat_status != DAT_SUCCESS )\r
180         {\r
181             /*\r
182              * Have a problem setting up the connection, something\r
183              * wrong!  Decrements the EVD refcount & release it.\r
184              */\r
185             dapl_os_atomic_dec (& ((DAPL_EVD *)evd_handle)->evd_ref_count);\r
186             sp_ptr->evd_handle = NULL;\r
187             dapls_ia_unlink_sp ( ia_ptr, sp_ptr );\r
188             dapls_sp_free_sp ( sp_ptr );\r
189 \r
190             dapl_dbg_log (DAPL_DBG_TYPE_CM, \r
191                       "--> dapl_psp_create setup_conn_listener failed: %x\n", \r
192                       dat_status);\r
193 \r
194             goto bail;\r
195         }\r
196     }\r
197 \r
198     /*\r
199      * Return handle to the user\r
200      */\r
201     *psp_handle = (DAT_PSP_HANDLE)sp_ptr;\r
202 \r
203  bail:\r
204     return dat_status;\r
205 }\r
206 \r
207 /*\r
208  * Local variables:\r
209  *  c-indent-level: 4\r
210  *  c-basic-offset: 4\r
211  *  c-brace-offset: -4\r
212  *  tab-width: 8\r
213  * End:\r
214  */\r