[IBAL] Check for invalid PD during AV creation.
[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         if( AL_OBJ_INVALID_HANDLE( h_pd, AL_OBJ_TYPE_H_PD ) )\r
126         {\r
127                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PD_HANDLE\n") );\r
128                 return IB_INVALID_PD_HANDLE;\r
129         }\r
130 \r
131         /* Get an AV tracking structure. */\r
132         h_av = alloc_av();\r
133         if( !h_av )\r
134                 return IB_INSUFFICIENT_MEMORY;\r
135 \r
136         status = attach_al_obj( &h_pd->obj, &h_av->obj );\r
137         if( status != IB_SUCCESS )\r
138         {\r
139                 h_av->obj.pfn_destroy( &h_av->obj, NULL );\r
140                 return status;\r
141         }\r
142 \r
143         /* Create the address vector. */\r
144         status = verbs_create_av( h_pd, p_av_attr, h_av );\r
145         if( status != IB_SUCCESS )\r
146         {\r
147                 h_av->obj.pfn_destroy( &h_av->obj, NULL );\r
148                 return status;\r
149         }\r
150 \r
151         /* keep a copy of the av for special qp access */\r
152         h_av->av_attr = *p_av_attr;\r
153         *ph_av = h_av;\r
154 \r
155         return IB_SUCCESS;\r
156 }\r
157 \r
158 \r
159 \r
160 ib_api_status_t\r
161 ib_destroy_av(\r
162         IN              const   ib_av_handle_t                          h_av )\r
163 {\r
164         CL_ENTER( AL_DBG_AV, g_al_dbg_lvl );\r
165 \r
166         if( AL_OBJ_INVALID_HANDLE( h_av, AL_OBJ_TYPE_H_AV ) )\r
167         {\r
168                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_AV_HANDLE\n") );\r
169                 return IB_INVALID_AV_HANDLE;\r
170         }\r
171 \r
172         ref_al_obj( &h_av->obj );\r
173         h_av->obj.pfn_destroy( &h_av->obj, NULL );\r
174 \r
175         CL_EXIT( AL_DBG_AV, g_al_dbg_lvl );\r
176         return IB_SUCCESS;\r
177 }\r
178 \r
179 \r
180 \r
181 static void\r
182 __cleanup_av(\r
183         IN                              struct _al_obj                          *p_obj )\r
184 {\r
185         ib_api_status_t                 status;\r
186         ib_av_handle_t                  h_av;\r
187 \r
188         CL_ASSERT( p_obj );\r
189         h_av = PARENT_STRUCT( p_obj, ib_av_t, obj );\r
190 \r
191         /* Destroy the AV. */\r
192         if( verbs_check_av( h_av ) )\r
193         {\r
194                 status = verbs_destroy_av(h_av);\r
195                 CL_ASSERT( status == IB_SUCCESS );\r
196 #ifndef CL_KERNEL\r
197                 h_av->obj.hdl = AL_INVALID_HANDLE;\r
198 #endif\r
199                 h_av->h_ci_av = NULL;\r
200         }\r
201 }\r
202 \r
203 \r
204 \r
205 static void\r
206 __return_av(\r
207         IN                              al_obj_t                                        *p_obj )\r
208 {\r
209         ib_av_handle_t                  h_av;\r
210 \r
211         h_av = PARENT_STRUCT( p_obj, ib_av_t, obj );\r
212         reset_al_obj( p_obj );\r
213         put_av( h_av );\r
214 }\r
215 \r
216 \r
217 \r
218 ib_api_status_t\r
219 ib_query_av(\r
220         IN              const   ib_av_handle_t                          h_av,\r
221                 OUT                     ib_av_attr_t* const                     p_av_attr,\r
222                 OUT                     ib_pd_handle_t* const           ph_pd )\r
223 {\r
224         return query_av( h_av, p_av_attr, ph_pd, NULL );\r
225 }\r
226 \r
227 \r
228 \r
229 ib_api_status_t\r
230 query_av(\r
231         IN              const   ib_av_handle_t                          h_av,\r
232                 OUT                     ib_av_attr_t* const                     p_av_attr,\r
233                 OUT                     ib_pd_handle_t* const           ph_pd,\r
234         IN      OUT                     ci_umv_buf_t* const                     p_umv_buf )\r
235 {\r
236         ib_api_status_t                 status;\r
237 \r
238         CL_ENTER( AL_DBG_AV, g_al_dbg_lvl );\r
239 \r
240         if( AL_OBJ_INVALID_HANDLE( h_av, AL_OBJ_TYPE_H_AV ) )\r
241         {\r
242                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_AV_HANDLE\n") );\r
243                 return IB_INVALID_AV_HANDLE;\r
244         }\r
245         if( !p_av_attr || !ph_pd )\r
246         {\r
247                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PARAMETER\n") );\r
248                 return IB_INVALID_PARAMETER;\r
249         }\r
250 \r
251         status = verbs_query_av(h_av, p_av_attr, ph_pd);\r
252 \r
253         /* Record AL's PD handle. */\r
254         if( status == IB_SUCCESS )\r
255         {\r
256                 *ph_pd = PARENT_STRUCT( h_av->obj.p_parent_obj, ib_pd_t, obj );\r
257                 h_av->av_attr = *p_av_attr;\r
258         }\r
259 \r
260         CL_EXIT( AL_DBG_AV, g_al_dbg_lvl );\r
261         return status;\r
262 }\r
263 \r
264 \r
265 \r
266 ib_api_status_t\r
267 ib_modify_av(\r
268         IN              const   ib_av_handle_t                          h_av,\r
269         IN              const   ib_av_attr_t* const                     p_av_mod )\r
270 {\r
271         return modify_av( h_av, p_av_mod, NULL );\r
272 }\r
273 \r
274 \r
275 ib_api_status_t\r
276 modify_av(\r
277         IN              const   ib_av_handle_t                          h_av,\r
278         IN              const   ib_av_attr_t* const                     p_av_mod,\r
279         IN      OUT                     ci_umv_buf_t* const                     p_umv_buf )\r
280 {\r
281         ib_api_status_t                 status;\r
282 \r
283         CL_ENTER( AL_DBG_AV, g_al_dbg_lvl );\r
284 \r
285         if( AL_OBJ_INVALID_HANDLE( h_av, AL_OBJ_TYPE_H_AV ) )\r
286         {\r
287                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_AV_HANDLE\n") );\r
288                 return IB_INVALID_AV_HANDLE;\r
289         }\r
290         if( !p_av_mod )\r
291         {\r
292                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PARAMETER\n") );\r
293                 return IB_INVALID_PARAMETER;\r
294         }\r
295 \r
296         status = verbs_modify_av(h_av, p_av_mod);\r
297 \r
298         /* Record av for special qp access */\r
299         if( status == IB_SUCCESS )\r
300         {\r
301                 h_av->av_attr = *p_av_mod;\r
302         }\r
303 \r
304         CL_EXIT( AL_DBG_AV, g_al_dbg_lvl );\r
305         return status;\r
306 }\r