[DAPL2] DAPL Counters & 2.0.3 extensions to support counter retrieval.
[mirror/winof/.git] / ulp / dapl2 / dapl / common / dapl_psp_free.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_free.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_free\r
46  *\r
47  * uDAPL: User Direct Access Program Library Version 1.1, 6.4.1.2\r
48  *\r
49  * Destroy a specific instance of a Service Point.\r
50  *\r
51  * Input:\r
52  *      psp_handle\r
53  *\r
54  * Output:\r
55  *      none\r
56  *\r
57  * Returns:\r
58  *      DAT_SUCCESS\r
59  *      DAT_INVALID_PARAMETER\r
60  */\r
61 DAT_RETURN DAT_API\r
62 dapl_psp_free (\r
63         IN      DAT_PSP_HANDLE     psp_handle )\r
64 {\r
65     DAPL_IA             *ia_ptr;\r
66     DAPL_SP             *sp_ptr;\r
67     DAT_RETURN          dat_status;\r
68     DAPL_SP_STATE       save_state;\r
69 \r
70     sp_ptr = (DAPL_SP *) psp_handle;\r
71     dat_status = DAT_SUCCESS;\r
72     /*\r
73      * Verify handle\r
74      */\r
75     dapl_dbg_log (DAPL_DBG_TYPE_CM, ">>> dapl_psp_free %p\n", psp_handle);\r
76 \r
77     if ( DAPL_BAD_HANDLE (sp_ptr, DAPL_MAGIC_PSP ) )\r
78     {\r
79         dat_status = DAT_ERROR (DAT_INVALID_HANDLE,DAT_INVALID_HANDLE_PSP);\r
80         goto bail;\r
81     }\r
82 \r
83     ia_ptr = sp_ptr->header.owner_ia;\r
84 \r
85     DAPL_CNTR(ia_ptr->header.owner_ia, DCNT_IA_PSP_FREE);\r
86 \r
87     /* \r
88      * Remove the connection listener if it has been established\r
89      * and there are no current connections in progress.\r
90      * If we defer removing the sp it becomes something of a zombie\r
91      * container until the last connection is disconnected, after\r
92      * which it will be cleaned up.\r
93      */\r
94     dapl_os_lock (&sp_ptr->header.lock);\r
95 \r
96     sp_ptr->listening = DAT_FALSE;\r
97 \r
98     /* Release reference on EVD. If an error was encountered in a previous\r
99      * free the evd_handle will be NULL\r
100      */\r
101     if (sp_ptr->evd_handle)\r
102     {\r
103         dapl_os_atomic_dec (& ((DAPL_EVD *)sp_ptr->evd_handle)->evd_ref_count);\r
104         sp_ptr->evd_handle = NULL;\r
105     }\r
106 \r
107     /*\r
108      * Release the base resource if there are no outstanding\r
109      * connections; else the last disconnect on this PSP will free it\r
110      * up. The PSP is used to contain CR records for each connection,\r
111      * which contain information necessary to disconnect.\r
112      */\r
113     dapl_dbg_log (DAPL_DBG_TYPE_CM,\r
114                   ">>> dapl_psp_free: state %d cr_list_count %d\n",\r
115                   sp_ptr->state, sp_ptr->cr_list_count );\r
116 \r
117     if ( (sp_ptr->state == DAPL_SP_STATE_PSP_LISTENING ||\r
118           sp_ptr->state == DAPL_SP_STATE_PSP_PENDING) &&\r
119          sp_ptr->cr_list_count == 0 )\r
120     {\r
121         save_state = sp_ptr->state;\r
122         sp_ptr->state = DAPL_SP_STATE_FREE;\r
123         dapl_os_unlock (&sp_ptr->header.lock);\r
124 \r
125         dat_status = dapls_ib_remove_conn_listener ( ia_ptr,\r
126                                                      sp_ptr );\r
127         if (dat_status != DAT_SUCCESS)\r
128         {\r
129             /* revert to entry state on error */\r
130             sp_ptr->state = save_state;\r
131             goto bail;\r
132         }\r
133         dapls_ia_unlink_sp ( ia_ptr, sp_ptr );\r
134         dapls_sp_free_sp ( sp_ptr );\r
135     }\r
136     else\r
137     {\r
138         /* The PSP is now in the pending state, where it will sit until\r
139          * the last connection terminates or the app uses the same\r
140          * ServiceID again, which will reactivate it.\r
141          */\r
142         sp_ptr->state = DAPL_SP_STATE_PSP_PENDING;\r
143         dapl_os_unlock (&sp_ptr->header.lock);\r
144         dapl_dbg_log (DAPL_DBG_TYPE_CM, ">>> dapl_psp_free: PSP PENDING\n");\r
145     }\r
146 \r
147  bail:\r
148     return dat_status;\r
149 }\r
150 \r
151 /*\r
152  * Local variables:\r
153  *  c-indent-level: 4\r
154  *  c-basic-offset: 4\r
155  *  c-brace-offset: -4\r
156  *  tab-width: 8\r
157  * End:\r
158  */\r