[IBAL, HCA] Provide HCA driver with UM CA handle for resource
[mirror/winof/.git] / core / al / al_pd.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 \r
35 #include "al.h"\r
36 #include "al_av.h"\r
37 #include "al_ca.h"\r
38 #include "al_cq.h"\r
39 #include "al_debug.h"\r
40 #include "al_mgr.h"\r
41 #include "al_mr.h"\r
42 #include "al_mw.h"\r
43 #include "al_pd.h"\r
44 #include "al_qp.h"\r
45 #include "al_verbs.h"\r
46 \r
47 #include "ib_common.h"\r
48 \r
49 \r
50 void\r
51 destroying_pd(\r
52         IN                              struct _al_obj                          *p_obj );\r
53 \r
54 \r
55 void\r
56 cleanup_pd(\r
57         IN                              struct _al_obj                          *p_obj );\r
58 \r
59 \r
60 void\r
61 free_pd(\r
62         IN                              al_obj_t                                        *p_obj );\r
63 \r
64 \r
65 \r
66 ib_api_status_t\r
67 alloc_pd(\r
68         IN              const   ib_ca_handle_t                          h_ca,\r
69         IN              const   ib_pd_type_t                            pd_type,\r
70         IN              const   void * const                            pd_context,\r
71                 OUT                     ib_pd_handle_t* const           ph_pd,\r
72         IN      OUT                     ci_umv_buf_t* const                     p_umv_buf )\r
73 {\r
74         ib_pd_handle_t                  h_pd;\r
75         ib_api_status_t                 status;\r
76         al_obj_type_t                   obj_type = AL_OBJ_TYPE_H_PD;\r
77 \r
78         CL_ASSERT( h_ca );\r
79 \r
80         if( !ph_pd )\r
81         {\r
82                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PARAMETER\n") );\r
83                 return IB_INVALID_PARAMETER;\r
84         }\r
85 \r
86         /* Allocate a protection domain. */\r
87         h_pd = (ib_pd_handle_t)cl_zalloc( sizeof( ib_pd_t ) );\r
88         if( !h_pd )\r
89         {\r
90                 return IB_INSUFFICIENT_MEMORY;\r
91         }\r
92 \r
93         if( p_umv_buf )\r
94                 obj_type |= AL_OBJ_SUBTYPE_UM_EXPORT;\r
95 \r
96         /* Construct the PD. */\r
97         construct_al_obj( &h_pd->obj, obj_type );\r
98         cl_qlist_init( &h_pd->mw_list );\r
99 \r
100         status = init_al_obj( &h_pd->obj, pd_context, TRUE,\r
101                 destroying_pd, cleanup_pd, free_pd );\r
102         if( status != IB_SUCCESS )\r
103         {\r
104                 free_pd( &h_pd->obj );\r
105                 return status;\r
106         }\r
107 \r
108         status = attach_al_obj( &h_ca->obj, &h_pd->obj );\r
109         if( status != IB_SUCCESS )\r
110         {\r
111                 h_pd->obj.pfn_destroy( &h_pd->obj, NULL );\r
112                 AL_TRACE_EXIT( AL_DBG_ERROR,\r
113                         ("attach_al_obj returned %s.\n", ib_get_err_str(status)) );\r
114                 return status;\r
115         }\r
116 \r
117         h_pd->type = pd_type;\r
118         switch( h_pd->type )\r
119         {\r
120         case IB_PDT_ALIAS:\r
121                 status = allocate_pd_alias( h_ca, h_pd );\r
122                 break;\r
123 \r
124         case IB_PDT_NORMAL:\r
125         case IB_PDT_SQP:\r
126         case IB_PDT_UD:\r
127                 /* Allocate the protection domain. */\r
128                 status = verbs_allocate_pd( h_ca, h_pd, p_umv_buf );\r
129                 break;\r
130 \r
131         default:\r
132                 CL_ASSERT( h_pd->type == IB_PDT_ALIAS || h_pd->type == IB_PDT_NORMAL );\r
133                 status = IB_INVALID_PARAMETER;\r
134         }\r
135 \r
136         if( status != IB_SUCCESS )\r
137         {\r
138                 h_pd->obj.pfn_destroy( &h_pd->obj, NULL );\r
139                 return status;\r
140         }\r
141 \r
142         *ph_pd = h_pd;\r
143 \r
144         return status;\r
145 }\r
146 \r
147 \r
148 \r
149 ib_api_status_t\r
150 ib_dealloc_pd(\r
151         IN              const   ib_pd_handle_t                          h_pd,\r
152         IN              const   ib_pfn_destroy_cb_t                     pfn_destroy_cb OPTIONAL )\r
153 {\r
154         CL_ENTER( AL_DBG_PD, g_al_dbg_lvl );\r
155 \r
156         if( AL_OBJ_INVALID_HANDLE( h_pd, AL_OBJ_TYPE_H_PD ) )\r
157         {\r
158                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PD_HANDLE\n") );\r
159                 return IB_INVALID_PD_HANDLE;\r
160         }\r
161 \r
162         ref_al_obj( &h_pd->obj );\r
163         h_pd->obj.pfn_destroy( &h_pd->obj, pfn_destroy_cb );\r
164 \r
165         CL_EXIT( AL_DBG_PD, g_al_dbg_lvl );\r
166         return IB_SUCCESS;\r
167 }\r
168 \r
169 \r
170 \r
171 /*\r
172  * Pre-destroy the protection domain.\r
173  */\r
174 void\r
175 destroying_pd(\r
176         IN                              al_obj_t                                        *p_obj )\r
177 {\r
178         ib_al_handle_t                  h_al;\r
179         ib_ca_handle_t                  h_ca;\r
180         ib_pd_handle_t                  h_pd;\r
181         ib_mw_handle_t                  h_mw;\r
182         cl_list_item_t                  *p_list_item;\r
183         ib_api_status_t                 status;\r
184 \r
185         CL_ASSERT( p_obj );\r
186         h_pd = PARENT_STRUCT( p_obj, ib_pd_t, obj );\r
187 \r
188         /* Get the AL instance of this protection domain. */\r
189         p_obj = h_pd->obj.p_parent_obj;\r
190         h_ca = PARENT_STRUCT( p_obj, ib_ca_t, obj );\r
191         p_obj = h_ca->obj.p_parent_obj;\r
192         h_al = PARENT_STRUCT( p_obj, ib_al_t, obj );\r
193 \r
194         /*\r
195          * Deallocate all MW's before proceeding with destruction.  This ensures\r
196          * that all MW's have been destroyed before any MR's are.\r
197          */\r
198         p_list_item = cl_qlist_head( &h_pd->mw_list );\r
199         while( p_list_item != cl_qlist_end( &h_pd->mw_list ) )\r
200         {\r
201                 h_mw = PARENT_STRUCT( p_list_item, ib_mw_t, pd_list_item );\r
202                 status = ib_destroy_mw( h_mw );\r
203                 CL_ASSERT( status == IB_SUCCESS );\r
204 \r
205                 CL_ASSERT( p_list_item != cl_qlist_head( &h_pd->mw_list ) );\r
206                 p_list_item = cl_qlist_head( &h_pd->mw_list );\r
207         }\r
208 }\r
209 \r
210 \r
211 \r
212 void\r
213 cleanup_pd(\r
214         IN                              struct _al_obj                          *p_obj )\r
215 {\r
216         ib_pd_handle_t                  h_pd;\r
217         ib_api_status_t                 status;\r
218 \r
219         CL_ASSERT( p_obj );\r
220         h_pd = PARENT_STRUCT( p_obj, ib_pd_t, obj );\r
221 \r
222         /* Release the HW resources. */\r
223         if( verbs_check_pd(h_pd))\r
224         {\r
225                 if( h_pd->type != IB_PDT_ALIAS )\r
226                 {\r
227                         /* Deallocate the CI PD. */\r
228                         status = verbs_deallocate_pd(h_pd);\r
229                         CL_ASSERT( status == IB_SUCCESS );\r
230                 }\r
231                 else\r
232                 {\r
233                         deallocate_pd_alias( h_pd );\r
234                 }\r
235         }\r
236 }\r
237 \r
238 \r
239 \r
240 /*\r
241  * Release all resources associated with the protection domain.\r
242  */\r
243 void\r
244 free_pd(\r
245         IN                              al_obj_t                                        *p_obj )\r
246 {\r
247         ib_pd_handle_t                  h_pd;\r
248 \r
249         CL_ASSERT( p_obj );\r
250         h_pd = PARENT_STRUCT( p_obj, ib_pd_t, obj );\r
251 \r
252         destroy_al_obj( p_obj );\r
253         cl_free( h_pd );\r
254 }\r
255 \r
256 \r
257 \r
258 ib_api_status_t\r
259 ib_create_qp(\r
260         IN              const   ib_pd_handle_t                          h_pd,\r
261         IN              const   ib_qp_create_t* const           p_qp_create,\r
262         IN              const   void* const                                     qp_context,\r
263         IN              const   ib_pfn_event_cb_t                       pfn_qp_event_cb OPTIONAL,\r
264                 OUT                     ib_qp_handle_t* const           ph_qp )\r
265 {\r
266         ib_api_status_t                 status;\r
267 \r
268         CL_ENTER( AL_DBG_QP, g_al_dbg_lvl );\r
269 \r
270         if( AL_OBJ_INVALID_HANDLE( h_pd, AL_OBJ_TYPE_H_PD ) )\r
271         {\r
272                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PD_HANDLE\n") );\r
273                 return IB_INVALID_PD_HANDLE;\r
274         }\r
275 \r
276         status = create_qp(\r
277                 h_pd, p_qp_create, qp_context, pfn_qp_event_cb, ph_qp, NULL );\r
278 \r
279         /* Release the reference taken in init_al_obj (init_base_qp). */\r
280         if( status == IB_SUCCESS )\r
281                 deref_al_obj( &(*ph_qp)->obj );\r
282 \r
283         CL_EXIT( AL_DBG_QP, g_al_dbg_lvl );\r
284         return status;\r
285 }\r
286 \r
287 \r
288 \r
289 ib_api_status_t\r
290 ib_get_spl_qp(\r
291         IN              const   ib_pd_handle_t                          h_pd,\r
292         IN              const   ib_net64_t                                      port_guid,\r
293         IN              const   ib_qp_create_t* const           p_qp_create,\r
294         IN              const   void* const                                     qp_context,\r
295         IN              const   ib_pfn_event_cb_t                       pfn_qp_event_cb OPTIONAL,\r
296                 OUT                     ib_pool_key_t* const            p_pool_key OPTIONAL,\r
297                 OUT                     ib_qp_handle_t* const           ph_qp )\r
298 {\r
299         ib_api_status_t                 status;\r
300 \r
301         CL_ENTER( AL_DBG_QP, g_al_dbg_lvl );\r
302 \r
303         if( AL_OBJ_INVALID_HANDLE( h_pd, AL_OBJ_TYPE_H_PD ) )\r
304         {\r
305                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PD_HANDLE\n") );\r
306                 return IB_INVALID_PD_HANDLE;\r
307         }\r
308 \r
309         status = get_spl_qp( h_pd, port_guid, p_qp_create, qp_context,\r
310                 pfn_qp_event_cb, p_pool_key, ph_qp, NULL );\r
311 \r
312         /* Release the reference taken in init_al_obj. */\r
313         if( status == IB_SUCCESS )\r
314                 deref_al_obj( &(*ph_qp)->obj );\r
315 \r
316         CL_EXIT( AL_DBG_QP, g_al_dbg_lvl );\r
317         return status;\r
318 }\r
319 \r
320 \r
321 \r
322 ib_api_status_t\r
323 ib_create_av(\r
324         IN              const   ib_pd_handle_t                          h_pd,\r
325         IN              const   ib_av_attr_t* const                     p_av_attr,\r
326                 OUT                     ib_av_handle_t* const           ph_av )\r
327 {\r
328         ib_api_status_t                 status;\r
329 \r
330         CL_ENTER( AL_DBG_AV, g_al_dbg_lvl );\r
331 \r
332         if( AL_OBJ_INVALID_HANDLE( h_pd, AL_OBJ_TYPE_H_PD ) )\r
333         {\r
334                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PD_HANDLE\n") );\r
335                 return IB_INVALID_PD_HANDLE;\r
336         }\r
337 \r
338         status = create_av( h_pd, p_av_attr, ph_av, NULL );\r
339 \r
340         /* Release the reference taken in alloc_av. */\r
341         if( status == IB_SUCCESS )\r
342                 deref_al_obj( &(*ph_av)->obj );\r
343 \r
344         CL_EXIT( AL_DBG_AV, g_al_dbg_lvl );\r
345         return status;\r
346 }\r
347 \r
348 \r
349 \r
350 ib_api_status_t\r
351 ib_create_mw(\r
352         IN              const   ib_pd_handle_t                          h_pd,\r
353                 OUT                     net32_t* const                          p_rkey,\r
354                 OUT                     ib_mw_handle_t* const           ph_mw )\r
355 {\r
356         ib_api_status_t                 status;\r
357 \r
358         CL_ENTER( AL_DBG_MW, g_al_dbg_lvl );\r
359 \r
360         if( AL_OBJ_INVALID_HANDLE( h_pd, AL_OBJ_TYPE_H_PD ) )\r
361         {\r
362                 CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl, ("IB_INVALID_PD_HANDLE\n") );\r
363                 return IB_INVALID_PD_HANDLE;\r
364         }\r
365 \r
366         status = create_mw( h_pd, p_rkey, ph_mw, NULL );\r
367 \r
368         if( status == IB_SUCCESS )\r
369                 deref_al_obj( &(*ph_mw)->obj );\r
370 \r
371         CL_EXIT( AL_DBG_MW, g_al_dbg_lvl );\r
372         return status;\r
373 }\r
374 \r
375 \r
376 \r
377 void\r
378 pd_insert_mw(\r
379         IN              const   ib_mw_handle_t                          h_mw )\r
380 {\r
381         ib_pd_handle_t          h_pd;\r
382 \r
383         CL_ASSERT( h_mw );\r
384         h_pd = PARENT_STRUCT( h_mw->obj.p_parent_obj, ib_pd_t, obj );\r
385 \r
386         cl_spinlock_acquire( &h_pd->obj.lock );\r
387         cl_qlist_insert_tail( &h_pd->mw_list, &h_mw->pd_list_item );\r
388         cl_spinlock_release( &h_pd->obj.lock );\r
389 }\r
390 \r
391 \r
392 \r
393 void\r
394 pd_remove_mw(\r
395         IN              const   ib_mw_handle_t                          h_mw )\r
396 {\r
397         ib_pd_handle_t          h_pd;\r
398 \r
399         CL_ASSERT( h_mw );\r
400         h_pd = PARENT_STRUCT( h_mw->obj.p_parent_obj, ib_pd_t, obj );\r
401 \r
402         cl_spinlock_acquire( &h_pd->obj.lock );\r
403         cl_qlist_remove_item( &h_pd->mw_list, &h_mw->pd_list_item );\r
404         cl_spinlock_release( &h_pd->obj.lock );\r
405 }\r