[DAPL2] DAPL Counters & 2.0.3 extensions to support counter retrieval.
[mirror/winof/.git] / ulp / dapl2 / dapl / udapl / dapl_lmr_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_lmr_create.c\r
31  *\r
32  * PURPOSE: Memory management\r
33  *\r
34  * $Id:$\r
35  **********************************************************************/\r
36 \r
37 #include "dapl_lmr_util.h"\r
38 #include "dapl_adapter_util.h"\r
39 #include "dapl_vendor.h"\r
40 \r
41 /*********************************************************************\r
42  *                                                                   *\r
43  * Function Prototypes                                               *\r
44  *                                                                   *\r
45  *********************************************************************/\r
46 \r
47 STATIC _INLINE_ DAT_RETURN\r
48 dapli_lmr_create_virtual (      \r
49     IN  DAPL_IA                 *ia,\r
50     IN  DAT_PVOID               virt_addr,\r
51     IN  DAT_VLEN                length,\r
52     IN  DAPL_PZ                 *pz,\r
53     IN  DAT_MEM_PRIV_FLAGS      privileges,\r
54     IN  DAT_VA_TYPE             va_type,\r
55     OUT DAT_LMR_HANDLE          *lmr_handle,\r
56     OUT DAT_LMR_CONTEXT         *lmr_context,\r
57     OUT DAT_RMR_CONTEXT         *rmr_context,\r
58     OUT DAT_VLEN                *registered_length,\r
59     OUT DAT_VADDR               *registered_address );\r
60 \r
61 STATIC _INLINE_ DAT_RETURN\r
62 dapli_lmr_create_lmr (    \r
63     IN  DAPL_IA                 *ia,\r
64     IN  DAPL_LMR                *original_lmr,\r
65     IN  DAPL_PZ                 *pz,\r
66     IN  DAT_MEM_PRIV_FLAGS      privileges,\r
67     IN  DAT_VA_TYPE             va_type,\r
68     OUT DAT_LMR_HANDLE          *lmr_handle,\r
69     OUT DAT_LMR_CONTEXT         *lmr_context,\r
70     OUT DAT_RMR_CONTEXT         *rmr_context,\r
71     OUT DAT_VLEN                *registered_length,\r
72     OUT DAT_VADDR               *registered_address );\r
73 \r
74 \r
75 STATIC _INLINE_ DAT_RETURN\r
76 dapli_lmr_create_shared (\r
77     IN  DAPL_IA                 *ia,\r
78     IN  DAT_REGION_DESCRIPTION  reg_desc,\r
79     IN  DAT_VLEN                length,\r
80     IN  DAPL_PZ                 *pz,\r
81     IN  DAT_MEM_PRIV_FLAGS      privileges,\r
82     IN  DAT_VA_TYPE             va_type,\r
83     OUT DAT_LMR_HANDLE          *lmr_handle,\r
84     OUT DAT_LMR_CONTEXT         *lmr_context,\r
85     OUT DAT_RMR_CONTEXT         *rmr_context,\r
86     OUT DAT_VLEN                *registered_length,\r
87     OUT DAT_VADDR               *registered_address );\r
88 \r
89 /*********************************************************************\r
90  *                                                                   *\r
91  * Function Definitions                                              *\r
92  *                                                                   *\r
93  *********************************************************************/\r
94 \r
95 DAT_RETURN\r
96 dapli_lmr_create_virtual (      \r
97     IN  DAPL_IA                 *ia,\r
98     IN  DAT_PVOID               virt_addr,\r
99     IN  DAT_VLEN                length,\r
100     IN  DAPL_PZ                 *pz,\r
101     IN  DAT_MEM_PRIV_FLAGS      privileges,\r
102     IN  DAT_VA_TYPE             va_type,\r
103     OUT DAT_LMR_HANDLE          *lmr_handle,\r
104     OUT DAT_LMR_CONTEXT         *lmr_context,\r
105     OUT DAT_RMR_CONTEXT         *rmr_context,\r
106     OUT DAT_VLEN                *registered_length,\r
107     OUT DAT_VADDR               *registered_address )\r
108 {\r
109     DAPL_LMR                    *lmr;\r
110     DAT_REGION_DESCRIPTION      reg_desc;\r
111     DAT_RETURN                  dat_status;\r
112 \r
113     reg_desc.for_va = virt_addr;\r
114     dat_status = DAT_SUCCESS;\r
115 \r
116     lmr = dapl_lmr_alloc (ia, \r
117                          DAT_MEM_TYPE_VIRTUAL,\r
118                          reg_desc,\r
119                          length,\r
120                          (DAT_PZ_HANDLE) pz, \r
121                          privileges);\r
122 \r
123     if ( NULL == lmr )\r
124     {\r
125         dat_status = DAT_ERROR (DAT_INSUFFICIENT_RESOURCES,DAT_RESOURCE_MEMORY);\r
126         goto bail;\r
127     }\r
128 \r
129     dat_status = dapls_ib_mr_register (ia,\r
130                                        lmr,\r
131                                        virt_addr,\r
132                                        length,\r
133                                        privileges,\r
134                                        va_type);\r
135 \r
136     if (DAT_SUCCESS != dat_status)\r
137     {\r
138         dapl_lmr_dealloc (lmr);\r
139         goto bail;\r
140     }\r
141 \r
142     /* if the LMR context is already in the hash table */\r
143     dat_status =  dapls_hash_search (ia->hca_ptr->lmr_hash_table, \r
144                                      lmr->param.lmr_context,\r
145                                      NULL);\r
146     if (dat_status == DAT_SUCCESS)\r
147     {\r
148         (void)dapls_ib_mr_deregister (lmr);\r
149         dapl_lmr_dealloc (lmr);\r
150 \r
151         dat_status = DAT_ERROR (DAT_INVALID_STATE,DAT_INVALID_STATE_LMR_IN_USE);\r
152         goto bail;\r
153     }\r
154 \r
155     dat_status = dapls_hash_insert (ia->hca_ptr->lmr_hash_table, \r
156                                     lmr->param.lmr_context,\r
157                                     lmr);\r
158     if (dat_status != DAT_SUCCESS)\r
159     {\r
160         (void)dapls_ib_mr_deregister (lmr);\r
161         dapl_lmr_dealloc (lmr);\r
162 \r
163         /* The value returned by dapls_hash_insert(.) is not    */\r
164         /* returned to the consumer because the spec. requires */\r
165         /* that dat_lmr_create(.) return only certain values.  */\r
166         dat_status = DAT_ERROR (DAT_INSUFFICIENT_RESOURCES,DAT_RESOURCE_MEMORY);\r
167         goto bail;\r
168     }\r
169 \r
170     dapl_os_atomic_inc (&pz->pz_ref_count);\r
171     *lmr_handle = (DAT_LMR_HANDLE) lmr;\r
172 \r
173     if (NULL != lmr_context)\r
174     {\r
175         *lmr_context = lmr->param.lmr_context;\r
176     }\r
177     if (NULL != rmr_context)\r
178     {\r
179         *rmr_context = lmr->param.rmr_context;\r
180     }\r
181     if (NULL != registered_length)\r
182     {\r
183         *registered_length =  lmr->param.registered_size;\r
184     }\r
185     if (NULL != registered_address)\r
186     {\r
187         *registered_address = lmr->param.registered_address;\r
188     }\r
189 \r
190  bail:\r
191     return dat_status;\r
192 }\r
193 \r
194 \r
195 DAT_RETURN\r
196 dapli_lmr_create_lmr (    \r
197     IN  DAPL_IA                 *ia,\r
198     IN  DAPL_LMR                *original_lmr,\r
199     IN  DAPL_PZ                 *pz,\r
200     IN  DAT_MEM_PRIV_FLAGS      privileges,\r
201     IN  DAT_VA_TYPE             va_type,\r
202     OUT DAT_LMR_HANDLE          *lmr_handle,\r
203     OUT DAT_LMR_CONTEXT         *lmr_context,\r
204     OUT DAT_RMR_CONTEXT         *rmr_context,\r
205     OUT DAT_VLEN                *registered_length,\r
206     OUT DAT_VADDR               *registered_address )\r
207 {\r
208     DAPL_LMR                    *lmr;\r
209     DAT_REGION_DESCRIPTION      reg_desc;\r
210     DAT_RETURN                  dat_status;\r
211 \r
212     dapl_dbg_log (DAPL_DBG_TYPE_API,\r
213                   "dapl_lmr_create_lmr (%p, %p, %p, %x, %x, %p, %p, %p, %p)\n",\r
214                   ia,\r
215                   original_lmr, \r
216                   pz, privileges, va_type,\r
217                   lmr_handle, \r
218                   lmr_context, \r
219                   registered_length, \r
220                   registered_address);\r
221 \r
222     dat_status = dapls_hash_search (ia->hca_ptr->lmr_hash_table, \r
223                                     original_lmr->param.lmr_context, \r
224                                     (DAPL_HASH_DATA *) &lmr);\r
225      if ( dat_status != DAT_SUCCESS )\r
226     {\r
227         dat_status = DAT_ERROR (DAT_INVALID_PARAMETER,DAT_INVALID_ARG2);\r
228         goto bail;\r
229     }\r
230 \r
231     reg_desc.for_lmr_handle = (DAT_LMR_HANDLE) original_lmr;\r
232 \r
233     lmr = dapl_lmr_alloc (ia, \r
234                           DAT_MEM_TYPE_LMR,\r
235                           reg_desc,\r
236                           original_lmr->param.length,\r
237                           (DAT_PZ_HANDLE) pz,\r
238                           privileges);\r
239 \r
240     if (NULL == lmr)\r
241     {\r
242         dat_status = DAT_ERROR (DAT_INSUFFICIENT_RESOURCES,DAT_RESOURCE_MEMORY);\r
243         goto bail;\r
244     }\r
245 \r
246     dat_status = dapls_ib_mr_register_shared (ia,\r
247                                               lmr,\r
248                                               privileges,\r
249                                               va_type);\r
250 \r
251     if (DAT_SUCCESS != dat_status)\r
252     {\r
253         dapl_lmr_dealloc (lmr);\r
254         goto bail;\r
255     }\r
256 \r
257     /* if the LMR context is already in the hash table */\r
258     dat_status = dapls_hash_search (ia->hca_ptr->lmr_hash_table, \r
259                                     lmr->param.lmr_context,\r
260                                     NULL);\r
261     if (dat_status == DAT_SUCCESS)\r
262     {\r
263         dapls_ib_mr_deregister (lmr);\r
264         dapl_lmr_dealloc (lmr);\r
265 \r
266         dat_status = DAT_ERROR (DAT_INVALID_STATE,DAT_INVALID_STATE_LMR_IN_USE);\r
267         goto bail;\r
268     }\r
269 \r
270     dat_status = dapls_hash_insert (ia->hca_ptr->lmr_hash_table, \r
271                                     lmr->param.lmr_context,\r
272                                     lmr);\r
273     if (dat_status != DAT_SUCCESS)\r
274     {\r
275         dapls_ib_mr_deregister (lmr);\r
276         dapl_lmr_dealloc (lmr);\r
277 \r
278         /* The value returned by dapls_hash_insert(.) is not    */\r
279         /* returned to the consumer because the spec. requires */\r
280         /* that dat_lmr_create(.) return only certain values.  */\r
281         dat_status = DAT_ERROR (DAT_INSUFFICIENT_RESOURCES,DAT_RESOURCE_MEMORY);\r
282         goto bail;\r
283     }\r
284 \r
285     dapl_os_atomic_inc (&pz->pz_ref_count);\r
286     *lmr_handle = (DAT_LMR_HANDLE) lmr;\r
287 \r
288     if (NULL != lmr_context)\r
289     {\r
290         *lmr_context = lmr->param.lmr_context;\r
291     }\r
292     if (NULL != rmr_context)\r
293     {\r
294         *rmr_context = lmr->param.rmr_context;\r
295     }\r
296     if (NULL != registered_length)\r
297     {\r
298         *registered_length = lmr->param.registered_size;\r
299     }\r
300     if (NULL != registered_address)\r
301     {\r
302         *registered_address = lmr->param.registered_address;\r
303     }\r
304 \r
305  bail:\r
306     return dat_status;\r
307 }\r
308 \r
309 \r
310 \r
311 DAT_RETURN\r
312 dapli_lmr_create_shared (\r
313     IN  DAPL_IA                 *ia,\r
314     IN  DAT_REGION_DESCRIPTION  reg_desc,\r
315     IN  DAT_VLEN                length,\r
316     IN  DAPL_PZ                 *pz,\r
317     IN  DAT_MEM_PRIV_FLAGS      privileges,\r
318     IN  DAT_VA_TYPE             va_type,\r
319     OUT DAT_LMR_HANDLE          *lmr_handle,\r
320     OUT DAT_LMR_CONTEXT         *lmr_context,\r
321     OUT DAT_RMR_CONTEXT         *rmr_context,\r
322     OUT DAT_VLEN                *registered_length,\r
323     OUT DAT_VADDR               *registered_address )\r
324 {\r
325     DAPL_LMR                    *lmr;\r
326     DAT_RETURN                  dat_status;\r
327 \r
328     dat_status = DAT_SUCCESS;\r
329 \r
330     dapl_dbg_log (DAPL_DBG_TYPE_API,\r
331                   "dapl_lmr_create_shared_virtual (ia=%p len=%x pz=%p priv=%x)\n",\r
332                   ia,\r
333                   length,\r
334                   pz, privileges);\r
335 \r
336     lmr = dapl_lmr_alloc (ia, \r
337                           DAT_MEM_TYPE_LMR,\r
338                           reg_desc,\r
339                           length, /* length is meaningless */\r
340                           (DAT_PZ_HANDLE) pz,\r
341                           privileges);\r
342 \r
343     if (NULL == lmr)\r
344     {\r
345         dat_status = DAT_ERROR (DAT_INSUFFICIENT_RESOURCES,DAT_RESOURCE_MEMORY);\r
346         goto bail;\r
347     }\r
348 \r
349     /*\r
350      * Added for the shared memory support - - -\r
351      * Save the region description.  We need to copy the shared\r
352      * memory id because the region_desc only contains a pointer\r
353      * to it.\r
354      */\r
355     dapl_os_memcpy(&lmr->shmid,\r
356                    reg_desc.for_shared_memory.shared_memory_id,\r
357                    sizeof(lmr->shmid));\r
358     lmr->param.region_desc = reg_desc;\r
359     lmr->param.length      = length;\r
360     lmr->param.mem_type    = DAT_MEM_TYPE_SHARED_VIRTUAL;\r
361     lmr->param.region_desc.for_shared_memory.shared_memory_id = &lmr->shmid;\r
362 \r
363     dat_status = dapls_ib_mr_register_shared(ia, lmr, privileges, va_type);\r
364     if (dat_status != DAT_SUCCESS)\r
365     {\r
366         dapl_lmr_dealloc (lmr);\r
367         dat_status = DAT_ERROR (DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY_REGION);\r
368         goto bail;\r
369     }\r
370 \r
371     /* if the LMR context is already in the hash table */\r
372     dat_status = dapls_hash_search(ia->hca_ptr->lmr_hash_table, \r
373                                    lmr->param.lmr_context,\r
374                                    NULL);\r
375     if (DAT_SUCCESS == dat_status)\r
376     {\r
377         (void)dapls_ib_mr_deregister (lmr);\r
378         dapl_lmr_dealloc (lmr);\r
379 \r
380         dat_status = DAT_ERROR (DAT_INVALID_STATE,DAT_INVALID_STATE_LMR_IN_USE);\r
381         goto bail;\r
382     }\r
383     \r
384     dat_status = dapls_hash_insert(ia->hca_ptr->lmr_hash_table, \r
385                                    lmr->param.lmr_context,\r
386                                    lmr);\r
387     if (dat_status != DAT_SUCCESS)\r
388     {\r
389         (void)dapls_ib_mr_deregister (lmr);\r
390         dapl_lmr_dealloc (lmr);\r
391 \r
392         /* The value returned by dapls_hash_insert(.) is not    */\r
393         /* returned to the consumer because the spec. requires */\r
394         /* that dat_lmr_create(.) return only certain values.  */\r
395         dat_status = DAT_ERROR (DAT_INSUFFICIENT_RESOURCES,DAT_RESOURCE_MEMORY);\r
396         goto bail;\r
397     }\r
398 \r
399     dapl_os_atomic_inc (&pz->pz_ref_count);\r
400     *lmr_handle = (DAT_LMR_HANDLE) lmr;\r
401 \r
402     if (NULL != lmr_context)\r
403     {\r
404         *lmr_context = (DAT_LMR_CONTEXT) lmr->param.lmr_context;\r
405     }\r
406     if (NULL != rmr_context)\r
407     {\r
408         *rmr_context = (DAT_LMR_CONTEXT) lmr->param.rmr_context;\r
409     }\r
410     if (NULL != registered_length)\r
411     {\r
412         *registered_length = lmr->param.length;\r
413     }\r
414     if (NULL != registered_address)\r
415     {\r
416         *registered_address = (DAT_VADDR) (uintptr_t) \r
417                 lmr->param.region_desc.for_shared_memory.virtual_address;\r
418     }\r
419  bail:\r
420 \r
421     return dat_status;\r
422 }\r
423 \r
424 \r
425 /*\r
426  * dapl_lmr_create\r
427  *\r
428  * Register a memory region with an Interface Adaptor.\r
429  *\r
430  * Input:\r
431  *      ia_handle\r
432  *      mem_type\r
433  *      region_description\r
434  *      length\r
435  *      pz_handle\r
436  *      privileges\r
437  *\r
438  * Output:\r
439  *      lmr_handle\r
440  *      lmr_context\r
441  *      registered_length\r
442  *      registered_address\r
443  *\r
444  * Returns:\r
445  *      DAT_SUCCESS\r
446  *      DAT_INSUFFICIENT_RESOURCES\r
447  *      DAT_INVALID_PARAMETER\r
448  *      DAT_INVALID_HANDLE\r
449  *      DAT_INVALID_STATE\r
450  *      DAT_MODEL_NOT_SUPPORTED\r
451  *\r
452  */\r
453 DAT_RETURN DAT_API\r
454 dapl_lmr_create (\r
455         IN      DAT_IA_HANDLE           ia_handle,\r
456         IN      DAT_MEM_TYPE            mem_type,\r
457         IN      DAT_REGION_DESCRIPTION  region_description,\r
458         IN      DAT_VLEN                length,\r
459         IN      DAT_PZ_HANDLE           pz_handle,\r
460         IN      DAT_MEM_PRIV_FLAGS      privileges,\r
461         IN      DAT_VA_TYPE             va_type,\r
462         OUT     DAT_LMR_HANDLE          *lmr_handle,\r
463         OUT     DAT_LMR_CONTEXT         *lmr_context,\r
464         OUT     DAT_RMR_CONTEXT         *rmr_context,\r
465         OUT     DAT_VLEN                *registered_length,\r
466         OUT     DAT_VADDR               *registered_address )\r
467 {\r
468     DAPL_IA             *ia;\r
469     DAPL_PZ             *pz;\r
470     DAT_RETURN          dat_status;\r
471 \r
472     if ( DAPL_BAD_HANDLE (ia_handle, DAPL_MAGIC_IA) )\r
473     {\r
474         dat_status = DAT_ERROR (DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);\r
475         goto bail;\r
476     }\r
477     if ( DAPL_BAD_HANDLE (pz_handle, DAPL_MAGIC_PZ) )\r
478     {\r
479         dat_status = DAT_ERROR (DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_PZ);\r
480         goto bail;\r
481     }\r
482     if (NULL == lmr_handle)\r
483     {\r
484         dat_status = DAT_ERROR (DAT_INVALID_PARAMETER, DAT_INVALID_ARG7);\r
485         goto bail;\r
486     }\r
487 \r
488     ia = (DAPL_IA *) ia_handle;\r
489     pz = (DAPL_PZ *) pz_handle;\r
490 \r
491     DAPL_CNTR(ia, DCNT_IA_LMR_CREATE);  \r
492 \r
493     switch (mem_type)\r
494     {\r
495         case DAT_MEM_TYPE_VIRTUAL:\r
496         {\r
497             dat_status = dapli_lmr_create_virtual ( \r
498                 ia, region_description.for_va, length, pz, privileges, va_type, \r
499                 lmr_handle, lmr_context, rmr_context, registered_length, \r
500                 registered_address);\r
501             break;\r
502         }\r
503         case DAT_MEM_TYPE_LMR:\r
504         {\r
505             DAPL_LMR *lmr;\r
506 \r
507             if ( DAPL_BAD_HANDLE (region_description.for_lmr_handle, DAPL_MAGIC_LMR) )\r
508             {\r
509                 dat_status = DAT_ERROR (DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_LMR);\r
510                 goto bail;\r
511             }\r
512 \r
513             lmr = (DAPL_LMR *) region_description.for_lmr_handle;\r
514 \r
515             dat_status = dapli_lmr_create_lmr (\r
516                 ia, lmr, pz, privileges, va_type, lmr_handle, \r
517                 lmr_context, rmr_context, registered_length, registered_address);\r
518             break;\r
519         }\r
520         case DAT_MEM_TYPE_SHARED_VIRTUAL:\r
521         {\r
522 #if (VN_MEM_SHARED_VIRTUAL_SUPPORT > 0)\r
523             dat_status =  dapli_lmr_create_shared (\r
524                 ia, region_description, length, pz, privileges, va_type,\r
525                 lmr_handle, lmr_context, rmr_context, registered_length,\r
526                 registered_address);\r
527 #else\r
528             dat_status = DAT_ERROR (DAT_NOT_IMPLEMENTED, DAT_NO_SUBTYPE);\r
529 #endif\r
530             break;\r
531         }\r
532         default:\r
533         {\r
534             dat_status = DAT_ERROR (DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);\r
535             break;\r
536         }\r
537     }\r
538 \r
539 bail:\r
540     return dat_status;\r
541 }\r