81f170b7a6ca089ea31db24f51fcf411bfba04ff
[mirror/winof/.git] / core / al / al_av.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. \r
4  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  *\r
30  * $Id$\r
31  */\r
32 \r
33 #include <iba/ib_al.h>\r
34 #include "al.h"\r
35 #include "al_av.h"\r
36 #include "al_debug.h"\r
37 #include "al_pd.h"\r
38 #include "al_res_mgr.h"\r
39 #include "al_verbs.h"\r
40 \r
41 \r
42 \r
43 static void\r
44 __cleanup_av(\r
45         IN                              struct _al_obj                          *p_obj );\r
46 \r
47 \r
48 static void\r
49 __return_av(\r
50         IN                              al_obj_t                                        *p_obj );\r
51 \r
52 \r
53 \r
54 cl_status_t\r
55 av_ctor(\r
56         IN                              void* const                                     p_object,\r
57         IN                              void*                                           context,\r
58                 OUT                     cl_pool_item_t** const          pp_pool_item )\r
59 {\r
60         ib_api_status_t                 status;\r
61         ib_av_handle_t                  h_av;\r
62 \r
63         UNUSED_PARAM( context );\r
64 \r
65         h_av = (ib_av_handle_t)p_object;\r
66         cl_memclr( h_av, sizeof( ib_av_t ) );\r
67 \r
68         construct_al_obj( &h_av->obj, AL_OBJ_TYPE_H_AV );\r
69         status = init_al_obj( &h_av->obj, NULL, FALSE, NULL,\r
70                 __cleanup_av, __return_av );\r
71         if( status != IB_SUCCESS )\r
72         {\r
73                 return CL_ERROR;\r
74         }\r
75 \r
76         *pp_pool_item = &((ib_av_handle_t)p_object)->obj.pool_item;\r
77 \r
78         /* Release the reference taken in init_al_obj. */\r
79         deref_al_obj( &h_av->obj );\r
80 \r
81         return CL_SUCCESS;\r
82 }\r
83 \r
84 \r
85 void\r
86 av_dtor(\r
87         IN              const   cl_pool_item_t* const           p_pool_item,\r
88         IN                              void*                                           context )\r
89 {\r
90         al_obj_t                                *p_obj;\r
91 \r
92         UNUSED_PARAM( context );\r
93 \r
94         p_obj = PARENT_STRUCT( p_pool_item, al_obj_t, pool_item );\r
95 \r
96         /*\r
97          * The AV is being totally destroyed.  Modify the free_cb to destroy the\r
98          * AL object.\r
99          */\r
100         p_obj->pfn_free = (al_pfn_free_t)destroy_al_obj;\r
101         ref_al_obj( p_obj );\r
102         p_obj->pfn_destroy( p_obj, NULL );\r
103 }\r
104 \r
105 \r
106 \r
107 ib_api_status_t\r
108 create_av(\r
109         IN              const   ib_pd_handle_t                          h_pd,\r
110         IN              const   ib_av_attr_t* const                     p_av_attr,\r
111                 OUT                     ib_av_handle_t* const           ph_av,\r
112         IN      OUT                     ci_umv_buf_t* const                     p_umv_buf )\r
113 {\r
114         ib_api_status_t                 status;\r
115         ib_av_handle_t                  h_av;\r
116 \r
117         CL_ASSERT( h_pd );\r
118 \r
119         if( !p_av_attr || !ph_av )\r
120         {\r
121                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PARAMETER\n") );\r
122                 return IB_INVALID_PARAMETER;\r
123         }\r
124 \r
125         /* Get an AV tracking structure. */\r
126         h_av = alloc_av();\r
127         if( !h_av )\r
128                 return IB_INSUFFICIENT_MEMORY;\r
129 \r
130         status = attach_al_obj( &h_pd->obj, &h_av->obj );\r
131         if( status != IB_SUCCESS )\r
132         {\r
133                 h_av->obj.pfn_destroy( &h_av->obj, NULL );\r
134                 return status;\r
135         }\r
136 \r
137         /* Create the address vector. */\r
138         status = verbs_create_av( h_pd, p_av_attr, h_av );\r
139         if( status != IB_SUCCESS )\r
140         {\r
141                 h_av->obj.pfn_destroy( &h_av->obj, NULL );\r
142                 return status;\r
143         }\r
144 \r
145         /* keep a copy of the av for special qp access */\r
146         h_av->av_attr = *p_av_attr;\r
147         *ph_av = h_av;\r
148 \r
149         return IB_SUCCESS;\r
150 }\r
151 \r
152 \r
153 \r
154 ib_api_status_t\r
155 ib_destroy_av(\r
156         IN              const   ib_av_handle_t                          h_av )\r
157 {\r
158         CL_ENTER( AL_DBG_AV, g_al_dbg_lvl );\r
159 \r
160         if( AL_OBJ_INVALID_HANDLE( h_av, AL_OBJ_TYPE_H_AV ) )\r
161         {\r
162                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_AV_HANDLE\n") );\r
163                 return IB_INVALID_AV_HANDLE;\r
164         }\r
165 \r
166         ref_al_obj( &h_av->obj );\r
167         h_av->obj.pfn_destroy( &h_av->obj, NULL );\r
168 \r
169         CL_EXIT( AL_DBG_AV, g_al_dbg_lvl );\r
170         return IB_SUCCESS;\r
171 }\r
172 \r
173 \r
174 \r
175 static void\r
176 __cleanup_av(\r
177         IN                              struct _al_obj                          *p_obj )\r
178 {\r
179         ib_api_status_t                 status;\r
180         ib_av_handle_t                  h_av;\r
181 \r
182         CL_ASSERT( p_obj );\r
183         h_av = PARENT_STRUCT( p_obj, ib_av_t, obj );\r
184 \r
185         /* Destroy the AV. */\r
186         if( verbs_check_av( h_av ) )\r
187         {\r
188                 status = verbs_destroy_av(h_av);\r
189                 CL_ASSERT( status == IB_SUCCESS );\r
190 #ifndef CL_KERNEL\r
191                 h_av->obj.hdl = AL_INVALID_HANDLE;\r
192 #endif\r
193                 h_av->h_ci_av = NULL;\r
194         }\r
195 }\r
196 \r
197 \r
198 \r
199 static void\r
200 __return_av(\r
201         IN                              al_obj_t                                        *p_obj )\r
202 {\r
203         ib_av_handle_t                  h_av;\r
204 \r
205         h_av = PARENT_STRUCT( p_obj, ib_av_t, obj );\r
206         reset_al_obj( p_obj );\r
207         put_av( h_av );\r
208 }\r
209 \r
210 \r
211 \r
212 ib_api_status_t\r
213 ib_query_av(\r
214         IN              const   ib_av_handle_t                          h_av,\r
215                 OUT                     ib_av_attr_t* const                     p_av_attr,\r
216                 OUT                     ib_pd_handle_t* const           ph_pd )\r
217 {\r
218         return query_av( h_av, p_av_attr, ph_pd, NULL );\r
219 }\r
220 \r
221 \r
222 \r
223 ib_api_status_t\r
224 query_av(\r
225         IN              const   ib_av_handle_t                          h_av,\r
226                 OUT                     ib_av_attr_t* const                     p_av_attr,\r
227                 OUT                     ib_pd_handle_t* const           ph_pd,\r
228         IN      OUT                     ci_umv_buf_t* const                     p_umv_buf )\r
229 {\r
230         ib_api_status_t                 status;\r
231 \r
232         CL_ENTER( AL_DBG_AV, g_al_dbg_lvl );\r
233 \r
234         if( AL_OBJ_INVALID_HANDLE( h_av, AL_OBJ_TYPE_H_AV ) )\r
235         {\r
236                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_AV_HANDLE\n") );\r
237                 return IB_INVALID_AV_HANDLE;\r
238         }\r
239         if( !p_av_attr || !ph_pd )\r
240         {\r
241                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PARAMETER\n") );\r
242                 return IB_INVALID_PARAMETER;\r
243         }\r
244 \r
245         status = verbs_query_av(h_av, p_av_attr, ph_pd);\r
246 \r
247         /* Record AL's PD handle. */\r
248         if( status == IB_SUCCESS )\r
249         {\r
250                 *ph_pd = PARENT_STRUCT( h_av->obj.p_parent_obj, ib_pd_t, obj );\r
251                 h_av->av_attr = *p_av_attr;\r
252         }\r
253 \r
254         CL_EXIT( AL_DBG_AV, g_al_dbg_lvl );\r
255         return status;\r
256 }\r
257 \r
258 \r
259 \r
260 ib_api_status_t\r
261 ib_modify_av(\r
262         IN              const   ib_av_handle_t                          h_av,\r
263         IN              const   ib_av_attr_t* const                     p_av_mod )\r
264 {\r
265         return modify_av( h_av, p_av_mod, NULL );\r
266 }\r
267 \r
268 \r
269 ib_api_status_t\r
270 modify_av(\r
271         IN              const   ib_av_handle_t                          h_av,\r
272         IN              const   ib_av_attr_t* const                     p_av_mod,\r
273         IN      OUT                     ci_umv_buf_t* const                     p_umv_buf )\r
274 {\r
275         ib_api_status_t                 status;\r
276 \r
277         CL_ENTER( AL_DBG_AV, g_al_dbg_lvl );\r
278 \r
279         if( AL_OBJ_INVALID_HANDLE( h_av, AL_OBJ_TYPE_H_AV ) )\r
280         {\r
281                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_AV_HANDLE\n") );\r
282                 return IB_INVALID_AV_HANDLE;\r
283         }\r
284         if( !p_av_mod )\r
285         {\r
286                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PARAMETER\n") );\r
287                 return IB_INVALID_PARAMETER;\r
288         }\r
289 \r
290         status = verbs_modify_av(h_av, p_av_mod);\r
291 \r
292         /* Record av for special qp access */\r
293         if( status == IB_SUCCESS )\r
294         {\r
295                 h_av->av_attr = *p_av_mod;\r
296         }\r
297 \r
298         CL_EXIT( AL_DBG_AV, g_al_dbg_lvl );\r
299         return status;\r
300 }\r