]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ofed/libibverbs/src/compat-1_0.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ofed / libibverbs / src / compat-1_0.c
1 /*
2  * Copyright (c) 2007 Cisco Systems, Inc.  All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32
33 #if HAVE_CONFIG_H
34 #  include <config.h>
35 #endif /* HAVE_CONFIG_H */
36
37 #include <string.h>
38 #include <stddef.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 #include <alloca.h>
42
43 #include "ibverbs.h"
44
45 struct ibv_pd_1_0 {
46         struct ibv_context_1_0 *context;
47         uint32_t                handle;
48
49         struct ibv_pd          *real_pd;
50 };
51
52 struct ibv_mr_1_0 {
53         struct ibv_context_1_0 *context;
54         struct ibv_pd_1_0      *pd;
55         uint32_t                handle;
56         uint32_t                lkey;
57         uint32_t                rkey;
58
59         struct ibv_mr          *real_mr;
60 };
61
62 struct ibv_srq_1_0 {
63         struct ibv_context_1_0 *context;
64         void                   *srq_context;
65         struct ibv_pd_1_0      *pd;
66         uint32_t                handle;
67
68         pthread_mutex_t         mutex;
69         pthread_cond_t          cond;
70         uint32_t                events_completed;
71
72         struct ibv_srq         *real_srq;
73 };
74
75 struct ibv_qp_init_attr_1_0 {
76         void                   *qp_context;
77         struct ibv_cq_1_0      *send_cq;
78         struct ibv_cq_1_0      *recv_cq;
79         struct ibv_srq_1_0     *srq;
80         struct ibv_qp_cap       cap;
81         enum ibv_qp_type        qp_type;
82         int                     sq_sig_all;
83 };
84
85 struct ibv_send_wr_1_0 {
86         struct ibv_send_wr_1_0 *next;
87         uint64_t                wr_id;
88         struct ibv_sge         *sg_list;
89         int                     num_sge;
90         enum ibv_wr_opcode      opcode;
91         int                     send_flags;
92         uint32_t                imm_data;       /* in network byte order */
93         union {
94                 struct {
95                         uint64_t        remote_addr;
96                         uint32_t        rkey;
97                 } rdma;
98                 struct {
99                         uint64_t        remote_addr;
100                         uint64_t        compare_add;
101                         uint64_t        swap;
102                         uint32_t        rkey;
103                 } atomic;
104                 struct {
105                         struct ibv_ah_1_0 *ah;
106                         uint32_t        remote_qpn;
107                         uint32_t        remote_qkey;
108                 } ud;
109         } wr;
110 };
111
112 struct ibv_recv_wr_1_0 {
113         struct ibv_recv_wr_1_0 *next;
114         uint64_t                wr_id;
115         struct ibv_sge         *sg_list;
116         int                     num_sge;
117 };
118
119 struct ibv_qp_1_0 {
120         struct ibv_context_1_0 *context;
121         void                   *qp_context;
122         struct ibv_pd_1_0      *pd;
123         struct ibv_cq_1_0      *send_cq;
124         struct ibv_cq_1_0      *recv_cq;
125         struct ibv_srq_1_0     *srq;
126         uint32_t                handle;
127         uint32_t                qp_num;
128         enum ibv_qp_state       state;
129         enum ibv_qp_type        qp_type;
130
131         pthread_mutex_t         mutex;
132         pthread_cond_t          cond;
133         uint32_t                events_completed;
134
135         struct ibv_qp          *real_qp;
136 };
137
138 struct ibv_cq_1_0 {
139         struct ibv_context_1_0 *context;
140         void                   *cq_context;
141         uint32_t                handle;
142         int                     cqe;
143
144         pthread_mutex_t         mutex;
145         pthread_cond_t          cond;
146         uint32_t                comp_events_completed;
147         uint32_t                async_events_completed;
148
149         struct ibv_cq          *real_cq;
150 };
151
152 struct ibv_ah_1_0 {
153         struct ibv_context_1_0 *context;
154         struct ibv_pd_1_0      *pd;
155         uint32_t                handle;
156
157         struct ibv_ah          *real_ah;
158 };
159
160 struct ibv_device_1_0 {
161         void                   *obsolete_sysfs_dev;
162         void                   *obsolete_sysfs_ibdev;
163         struct ibv_device      *real_device; /* was obsolete driver member */
164         struct ibv_device_ops   ops;
165 };
166
167 struct ibv_context_ops_1_0 {
168         int                     (*query_device)(struct ibv_context *context,
169                                               struct ibv_device_attr *device_attr);
170         int                     (*query_port)(struct ibv_context *context, uint8_t port_num,
171                                               struct ibv_port_attr *port_attr);
172         struct ibv_pd *         (*alloc_pd)(struct ibv_context *context);
173         int                     (*dealloc_pd)(struct ibv_pd *pd);
174         struct ibv_mr *         (*reg_mr)(struct ibv_pd *pd, void *addr, size_t length,
175                                           int access);
176         int                     (*dereg_mr)(struct ibv_mr *mr);
177         struct ibv_cq *         (*create_cq)(struct ibv_context *context, int cqe,
178                                              struct ibv_comp_channel *channel,
179                                              int comp_vector);
180         int                     (*poll_cq)(struct ibv_cq_1_0 *cq, int num_entries,
181                                            struct ibv_wc *wc);
182         int                     (*req_notify_cq)(struct ibv_cq_1_0 *cq,
183                                                  int solicited_only);
184         void                    (*cq_event)(struct ibv_cq *cq);
185         int                     (*resize_cq)(struct ibv_cq *cq, int cqe);
186         int                     (*destroy_cq)(struct ibv_cq *cq);
187         struct ibv_srq *        (*create_srq)(struct ibv_pd *pd,
188                                               struct ibv_srq_init_attr *srq_init_attr);
189         int                     (*modify_srq)(struct ibv_srq *srq,
190                                               struct ibv_srq_attr *srq_attr,
191                                               int srq_attr_mask);
192         int                     (*query_srq)(struct ibv_srq *srq,
193                                              struct ibv_srq_attr *srq_attr);
194         int                     (*destroy_srq)(struct ibv_srq *srq);
195         int                     (*post_srq_recv)(struct ibv_srq_1_0 *srq,
196                                                  struct ibv_recv_wr_1_0 *recv_wr,
197                                                  struct ibv_recv_wr_1_0 **bad_recv_wr);
198         struct ibv_qp *         (*create_qp)(struct ibv_pd *pd, struct ibv_qp_init_attr *attr);
199         int                     (*query_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr,
200                                             int attr_mask,
201                                             struct ibv_qp_init_attr *init_attr);
202         int                     (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr,
203                                              int attr_mask);
204         int                     (*destroy_qp)(struct ibv_qp *qp);
205         int                     (*post_send)(struct ibv_qp_1_0 *qp,
206                                              struct ibv_send_wr_1_0 *wr,
207                                              struct ibv_send_wr_1_0 **bad_wr);
208         int                     (*post_recv)(struct ibv_qp_1_0 *qp,
209                                              struct ibv_recv_wr_1_0 *wr,
210                                              struct ibv_recv_wr_1_0 **bad_wr);
211         struct ibv_ah *         (*create_ah)(struct ibv_pd *pd, struct ibv_ah_attr *attr);
212         int                     (*destroy_ah)(struct ibv_ah *ah);
213         int                     (*attach_mcast)(struct ibv_qp *qp, union ibv_gid *gid,
214                                                 uint16_t lid);
215         int                     (*detach_mcast)(struct ibv_qp *qp, union ibv_gid *gid,
216                                                 uint16_t lid);
217 };
218
219 struct ibv_context_1_0 {
220         struct ibv_device_1_0          *device;
221         struct ibv_context_ops_1_0      ops;
222         int                             cmd_fd;
223         int                             async_fd;
224         int                             num_comp_vectors;
225
226         struct ibv_context             *real_context; /* was abi_compat member */
227 };
228
229 struct ibv_device_1_0 **__ibv_get_device_list_1_0(int *num)
230 {
231         struct ibv_device **real_list;
232         struct ibv_device_1_0 **l;
233         int i, n;
234
235         real_list = ibv_get_device_list(&n);
236         if (!real_list)
237                 return NULL;
238
239         l = calloc(n + 2, sizeof (struct ibv_device_1_0 *));
240         if (!l)
241                 return NULL;
242
243         l[0] = (void *) real_list;
244
245         for (i = 0; i < n; ++i) {
246                 l[i + 1] = calloc(1, sizeof (struct ibv_device_1_0));
247                 if (!l[i + 1])
248                         goto fail;
249                 l[i + 1]->real_device = real_list[i];
250         }
251
252         if (num)
253                 *num = n;
254
255         return l + 1;
256
257 fail:
258         for (i = 1; i <= n; ++i)
259                 if (l[i])
260                         free(l[i]);
261         ibv_free_device_list(real_list);
262         return NULL;
263 }
264 symver(__ibv_get_device_list_1_0, ibv_get_device_list, IBVERBS_1.0);
265
266 void __ibv_free_device_list_1_0(struct ibv_device_1_0 **list)
267 {
268         struct ibv_device_1_0 **l = list;
269
270         while (*l) {
271                 free(*l);
272                 ++l;
273         }
274
275         ibv_free_device_list((void *) list[-1]);
276         free(list - 1);
277 }
278 symver(__ibv_free_device_list_1_0, ibv_free_device_list, IBVERBS_1.0);
279
280 const char *__ibv_get_device_name_1_0(struct ibv_device_1_0 *device)
281 {
282         return ibv_get_device_name(device->real_device);
283 }
284 symver(__ibv_get_device_name_1_0, ibv_get_device_name, IBVERBS_1.0);
285
286 uint64_t __ibv_get_device_guid_1_0(struct ibv_device_1_0 *device)
287 {
288         return ibv_get_device_guid(device->real_device);
289 }
290 symver(__ibv_get_device_guid_1_0, ibv_get_device_guid, IBVERBS_1.0);
291
292 static int poll_cq_wrapper_1_0(struct ibv_cq_1_0 *cq, int num_entries,
293                                struct ibv_wc *wc)
294 {
295         return cq->context->real_context->ops.poll_cq(cq->real_cq, num_entries, wc);
296 }
297
298 static int req_notify_cq_wrapper_1_0(struct ibv_cq_1_0 *cq, int sol_only)
299 {
300         return cq->context->real_context->ops.req_notify_cq(cq->real_cq, sol_only);
301 }
302
303 static int post_srq_recv_wrapper_1_0(struct ibv_srq_1_0 *srq, struct ibv_recv_wr_1_0 *wr,
304                                  struct ibv_recv_wr_1_0 **bad_wr)
305 {
306         struct ibv_recv_wr_1_0 *w;
307         struct ibv_recv_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr;
308         int ret;
309
310         for (w = wr; w; w = w->next) {
311                 real_wr = alloca(sizeof *real_wr);
312                 real_wr->wr_id   = w->wr_id;
313                 real_wr->sg_list = w->sg_list;
314                 real_wr->num_sge = w->num_sge;
315                 real_wr->next    = NULL;
316                 if (tail_wr)
317                         tail_wr->next = real_wr;
318                 else
319                         head_wr = real_wr;
320
321                 tail_wr = real_wr;
322         }
323
324         ret = srq->context->real_context->ops.post_srq_recv(srq->real_srq, head_wr,
325                                                             &real_bad_wr);
326
327         if (ret) {
328                 for (real_wr = head_wr, w = wr;
329                      real_wr;
330                      real_wr = real_wr->next, w = w->next)
331                         if (real_wr == real_bad_wr) {
332                                 *bad_wr = w;
333                                 break;
334                         }
335         }
336
337         return ret;
338 }
339
340 static int post_send_wrapper_1_0(struct ibv_qp_1_0 *qp, struct ibv_send_wr_1_0 *wr,
341                                  struct ibv_send_wr_1_0 **bad_wr)
342 {
343         struct ibv_send_wr_1_0 *w;
344         struct ibv_send_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr;
345         int is_ud = qp->qp_type == IBV_QPT_UD;
346         int ret;
347
348         for (w = wr; w; w = w->next) {
349                 real_wr = alloca(sizeof *real_wr);
350                 real_wr->wr_id = w->wr_id;
351                 real_wr->next  = NULL;
352
353                 memcpy(&real_wr->sg_list, &w->sg_list,
354                        sizeof *w - offsetof(struct ibv_send_wr, sg_list));
355
356                 if (is_ud)
357                         real_wr->wr.ud.ah = w->wr.ud.ah->real_ah;
358
359                 if (tail_wr)
360                         tail_wr->next = real_wr;
361                 else
362                         head_wr = real_wr;
363
364                 tail_wr = real_wr;
365         }
366
367         ret = qp->context->real_context->ops.post_send(qp->real_qp, head_wr,
368                                                        &real_bad_wr);
369
370         if (ret) {
371                 for (real_wr = head_wr, w = wr;
372                      real_wr;
373                      real_wr = real_wr->next, w = w->next)
374                         if (real_wr == real_bad_wr) {
375                                 *bad_wr = w;
376                                 break;
377                         }
378         }
379
380         return ret;
381 }
382
383 static int post_recv_wrapper_1_0(struct ibv_qp_1_0 *qp, struct ibv_recv_wr_1_0 *wr,
384                                  struct ibv_recv_wr_1_0 **bad_wr)
385 {
386         struct ibv_recv_wr_1_0 *w;
387         struct ibv_recv_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr;
388         int ret;
389
390         for (w = wr; w; w = w->next) {
391                 real_wr = alloca(sizeof *real_wr);
392                 real_wr->wr_id   = w->wr_id;
393                 real_wr->sg_list = w->sg_list;
394                 real_wr->num_sge = w->num_sge;
395                 real_wr->next    = NULL;
396                 if (tail_wr)
397                         tail_wr->next = real_wr;
398                 else
399                         head_wr = real_wr;
400
401                 tail_wr = real_wr;
402         }
403
404         ret = qp->context->real_context->ops.post_recv(qp->real_qp, head_wr,
405                                                        &real_bad_wr);
406
407         if (ret) {
408                 for (real_wr = head_wr, w = wr;
409                      real_wr;
410                      real_wr = real_wr->next, w = w->next)
411                         if (real_wr == real_bad_wr) {
412                                 *bad_wr = w;
413                                 break;
414                         }
415         }
416
417         return ret;
418 }
419
420 struct ibv_context_1_0 *__ibv_open_device_1_0(struct ibv_device_1_0 *device)
421 {
422         struct ibv_context     *real_ctx;
423         struct ibv_context_1_0 *ctx;
424
425         ctx = malloc(sizeof *ctx);
426         if (!ctx)
427                 return NULL;
428
429         real_ctx = ibv_open_device(device->real_device);
430         if (!real_ctx) {
431                 free(ctx);
432                 return NULL;
433         }
434
435         ctx->device       = device;
436         ctx->real_context = real_ctx;
437
438         ctx->ops.poll_cq       = poll_cq_wrapper_1_0;
439         ctx->ops.req_notify_cq = req_notify_cq_wrapper_1_0;
440         ctx->ops.post_send     = post_send_wrapper_1_0;
441         ctx->ops.post_recv     = post_recv_wrapper_1_0;
442         ctx->ops.post_srq_recv = post_srq_recv_wrapper_1_0;
443
444         return ctx;
445 }
446 symver(__ibv_open_device_1_0, ibv_open_device, IBVERBS_1.0);
447
448 int __ibv_close_device_1_0(struct ibv_context_1_0 *context)
449 {
450         int ret;
451
452         ret = ibv_close_device(context->real_context);
453         if (ret)
454                 return ret;
455
456         free(context);
457         return 0;
458 }
459 symver(__ibv_close_device_1_0, ibv_close_device, IBVERBS_1.0);
460
461 int __ibv_get_async_event_1_0(struct ibv_context_1_0 *context,
462                               struct ibv_async_event *event)
463 {
464         int ret;
465
466         ret = ibv_get_async_event(context->real_context, event);
467         if (ret)
468                 return ret;
469
470         switch (event->event_type) {
471         case IBV_EVENT_CQ_ERR:
472                 event->element.cq = event->element.cq->cq_context;
473                 break;
474
475         case IBV_EVENT_QP_FATAL:
476         case IBV_EVENT_QP_REQ_ERR:
477         case IBV_EVENT_QP_ACCESS_ERR:
478         case IBV_EVENT_COMM_EST:
479         case IBV_EVENT_SQ_DRAINED:
480         case IBV_EVENT_PATH_MIG:
481         case IBV_EVENT_PATH_MIG_ERR:
482         case IBV_EVENT_QP_LAST_WQE_REACHED:
483                 event->element.qp = event->element.qp->qp_context;
484                 break;
485
486         case IBV_EVENT_SRQ_ERR:
487         case IBV_EVENT_SRQ_LIMIT_REACHED:
488                 event->element.srq = event->element.srq->srq_context;
489                 break;
490
491         default:
492                 break;
493         }
494
495         return ret;
496 }
497 symver(__ibv_get_async_event_1_0, ibv_get_async_event, IBVERBS_1.0);
498
499 void __ibv_ack_async_event_1_0(struct ibv_async_event *event)
500 {
501         struct ibv_async_event real_event = *event;
502
503         switch (event->event_type) {
504         case IBV_EVENT_CQ_ERR:
505                 real_event.element.cq =
506                         ((struct ibv_cq_1_0 *) event->element.cq)->real_cq;
507                 break;
508
509         case IBV_EVENT_QP_FATAL:
510         case IBV_EVENT_QP_REQ_ERR:
511         case IBV_EVENT_QP_ACCESS_ERR:
512         case IBV_EVENT_COMM_EST:
513         case IBV_EVENT_SQ_DRAINED:
514         case IBV_EVENT_PATH_MIG:
515         case IBV_EVENT_PATH_MIG_ERR:
516         case IBV_EVENT_QP_LAST_WQE_REACHED:
517                 real_event.element.qp =
518                         ((struct ibv_qp_1_0 *) event->element.qp)->real_qp;
519                 break;
520
521         case IBV_EVENT_SRQ_ERR:
522         case IBV_EVENT_SRQ_LIMIT_REACHED:
523                 real_event.element.srq =
524                         ((struct ibv_srq_1_0 *) event->element.srq)->real_srq;
525                 break;
526
527         default:
528                 break;
529         }
530
531         ibv_ack_async_event(&real_event);
532 }
533 symver(__ibv_ack_async_event_1_0, ibv_ack_async_event, IBVERBS_1.0);
534
535 int __ibv_query_device_1_0(struct ibv_context_1_0 *context,
536                            struct ibv_device_attr *device_attr)
537 {
538         return ibv_query_device(context->real_context, device_attr);
539 }
540 symver(__ibv_query_device_1_0, ibv_query_device, IBVERBS_1.0);
541
542 int __ibv_query_port_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
543                          struct ibv_port_attr *port_attr)
544 {
545         return ibv_query_port(context->real_context, port_num, port_attr);
546 }
547 symver(__ibv_query_port_1_0, ibv_query_port, IBVERBS_1.0);
548
549 int __ibv_query_gid_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
550                         int index, union ibv_gid *gid)
551 {
552         return ibv_query_gid(context->real_context, port_num, index, gid);
553 }
554 symver(__ibv_query_gid_1_0, ibv_query_gid, IBVERBS_1.0);
555
556 int __ibv_query_pkey_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
557                          int index, uint16_t *pkey)
558 {
559         return ibv_query_pkey(context->real_context, port_num, index, pkey);
560 }
561 symver(__ibv_query_pkey_1_0, ibv_query_pkey, IBVERBS_1.0);
562
563 struct ibv_pd_1_0 *__ibv_alloc_pd_1_0(struct ibv_context_1_0 *context)
564 {
565         struct ibv_pd *real_pd;
566         struct ibv_pd_1_0 *pd;
567
568         pd = malloc(sizeof *pd);
569         if (!pd)
570                 return NULL;
571
572         real_pd = ibv_alloc_pd(context->real_context);
573         if (!real_pd) {
574                 free(pd);
575                 return NULL;
576         }
577
578         pd->context = context;
579         pd->real_pd = real_pd;
580
581         return pd;
582 }
583 symver(__ibv_alloc_pd_1_0, ibv_alloc_pd, IBVERBS_1.0);
584
585 int __ibv_dealloc_pd_1_0(struct ibv_pd_1_0 *pd)
586 {
587         int ret;
588
589         ret = ibv_dealloc_pd(pd->real_pd);
590         if (ret)
591                 return ret;
592
593         free(pd);
594         return 0;
595 }
596 symver(__ibv_dealloc_pd_1_0, ibv_dealloc_pd, IBVERBS_1.0);
597
598 struct ibv_mr_1_0 *__ibv_reg_mr_1_0(struct ibv_pd_1_0 *pd, void *addr,
599                                     size_t length, int access)
600 {
601         struct ibv_mr *real_mr;
602         struct ibv_mr_1_0 *mr;
603
604         mr = malloc(sizeof *mr);
605         if (!mr)
606                 return NULL;
607
608         real_mr = ibv_reg_mr(pd->real_pd, addr, length, access);
609         if (!real_mr) {
610                 free(mr);
611                 return NULL;
612         }
613
614         mr->context = pd->context;
615         mr->pd      = pd;
616         mr->lkey    = real_mr->lkey;
617         mr->rkey    = real_mr->rkey;
618         mr->real_mr = real_mr;
619
620         return mr;
621 }
622 symver(__ibv_reg_mr_1_0, ibv_reg_mr, IBVERBS_1.0);
623
624 int __ibv_dereg_mr_1_0(struct ibv_mr_1_0 *mr)
625 {
626         int ret;
627
628         ret = ibv_dereg_mr(mr->real_mr);
629         if (ret)
630                 return ret;
631
632         free(mr);
633         return 0;
634 }
635 symver(__ibv_dereg_mr_1_0, ibv_dereg_mr, IBVERBS_1.0);
636
637 struct ibv_cq_1_0 *__ibv_create_cq_1_0(struct ibv_context_1_0 *context, int cqe,
638                                        void *cq_context,
639                                        struct ibv_comp_channel *channel,
640                                        int comp_vector)
641 {
642         struct ibv_cq *real_cq;
643         struct ibv_cq_1_0 *cq;
644
645         cq = malloc(sizeof *cq);
646         if (!cq)
647                 return NULL;
648
649         real_cq = ibv_create_cq(context->real_context, cqe, cq_context,
650                                 channel, comp_vector);
651         if (!real_cq) {
652                 free(cq);
653                 return NULL;
654         }
655
656         cq->context    = context;
657         cq->cq_context = cq_context;
658         cq->cqe        = cqe;
659         cq->real_cq    = real_cq;
660
661         real_cq->cq_context = cq;
662
663         return cq;
664 }
665 symver(__ibv_create_cq_1_0, ibv_create_cq, IBVERBS_1.0);
666
667 int __ibv_resize_cq_1_0(struct ibv_cq_1_0 *cq, int cqe)
668 {
669         return ibv_resize_cq(cq->real_cq, cqe);
670 }
671 symver(__ibv_resize_cq_1_0, ibv_resize_cq, IBVERBS_1.0);
672
673 int __ibv_destroy_cq_1_0(struct ibv_cq_1_0 *cq)
674 {
675         int ret;
676
677         ret = ibv_destroy_cq(cq->real_cq);
678         if (ret)
679                 return ret;
680
681         free(cq);
682         return 0;
683 }
684 symver(__ibv_destroy_cq_1_0, ibv_destroy_cq, IBVERBS_1.0);
685
686 int __ibv_get_cq_event_1_0(struct ibv_comp_channel *channel,
687                            struct ibv_cq_1_0 **cq, void **cq_context)
688 {
689         struct ibv_cq *real_cq;
690         void *cq_ptr;
691         int ret;
692
693         ret = ibv_get_cq_event(channel, &real_cq, &cq_ptr);
694         if (ret)
695                 return ret;
696
697         *cq         = cq_ptr;
698         *cq_context = (*cq)->cq_context;
699
700         return 0;
701 }
702 symver(__ibv_get_cq_event_1_0, ibv_get_cq_event, IBVERBS_1.0);
703
704 void __ibv_ack_cq_events_1_0(struct ibv_cq_1_0 *cq, unsigned int nevents)
705 {
706         ibv_ack_cq_events(cq->real_cq, nevents);
707 }
708 symver(__ibv_ack_cq_events_1_0, ibv_ack_cq_events, IBVERBS_1.0);
709
710 struct ibv_srq_1_0 *__ibv_create_srq_1_0(struct ibv_pd_1_0 *pd,
711                                          struct ibv_srq_init_attr *srq_init_attr)
712 {
713         struct ibv_srq *real_srq;
714         struct ibv_srq_1_0 *srq;
715
716         srq = malloc(sizeof *srq);
717         if (!srq)
718                 return NULL;
719
720         real_srq = ibv_create_srq(pd->real_pd, srq_init_attr);
721         if (!real_srq) {
722                 free(srq);
723                 return NULL;
724         }
725
726         srq->context     = pd->context;
727         srq->srq_context = srq_init_attr->srq_context;
728         srq->pd          = pd;
729         srq->real_srq    = real_srq;
730
731         real_srq->srq_context = srq;
732
733         return srq;
734 }
735 symver(__ibv_create_srq_1_0, ibv_create_srq, IBVERBS_1.0);
736
737 int __ibv_modify_srq_1_0(struct ibv_srq_1_0 *srq,
738                          struct ibv_srq_attr *srq_attr,
739                          int srq_attr_mask)
740 {
741         return ibv_modify_srq(srq->real_srq, srq_attr, srq_attr_mask);
742 }
743 symver(__ibv_modify_srq_1_0, ibv_modify_srq, IBVERBS_1.0);
744
745 int __ibv_query_srq_1_0(struct ibv_srq_1_0 *srq, struct ibv_srq_attr *srq_attr)
746 {
747         return ibv_query_srq(srq->real_srq, srq_attr);
748 }
749 symver(__ibv_query_srq_1_0, ibv_query_srq, IBVERBS_1.0);
750
751 int __ibv_destroy_srq_1_0(struct ibv_srq_1_0 *srq)
752 {
753         int ret;
754
755         ret = ibv_destroy_srq(srq->real_srq);
756         if (ret)
757                 return ret;
758
759         free(srq);
760         return 0;
761 }
762 symver(__ibv_destroy_srq_1_0, ibv_destroy_srq, IBVERBS_1.0);
763
764 struct ibv_qp_1_0 *__ibv_create_qp_1_0(struct ibv_pd_1_0 *pd,
765                                        struct ibv_qp_init_attr_1_0 *qp_init_attr)
766 {
767         struct ibv_qp *real_qp;
768         struct ibv_qp_1_0 *qp;
769         struct ibv_qp_init_attr real_init_attr;
770
771         qp = malloc(sizeof *qp);
772         if (!qp)
773                 return NULL;
774
775         real_init_attr.qp_context = qp_init_attr->qp_context;
776         real_init_attr.send_cq    = qp_init_attr->send_cq->real_cq;
777         real_init_attr.recv_cq    = qp_init_attr->recv_cq->real_cq;
778         real_init_attr.srq        = qp_init_attr->srq ?
779                 qp_init_attr->srq->real_srq : NULL;
780         real_init_attr.cap        = qp_init_attr->cap;
781         real_init_attr.qp_type    = qp_init_attr->qp_type;
782         real_init_attr.sq_sig_all = qp_init_attr->sq_sig_all;
783
784         real_qp = ibv_create_qp(pd->real_pd, &real_init_attr);
785         if (!real_qp) {
786                 free(qp);
787                 return NULL;
788         }
789
790         qp->context    = pd->context;
791         qp->qp_context = qp_init_attr->qp_context;
792         qp->pd         = pd;
793         qp->send_cq    = qp_init_attr->send_cq;
794         qp->recv_cq    = qp_init_attr->recv_cq;
795         qp->srq        = qp_init_attr->srq;
796         qp->qp_type    = qp_init_attr->qp_type;
797         qp->qp_num     = real_qp->qp_num;
798         qp->real_qp    = real_qp;
799
800         qp_init_attr->cap = real_init_attr.cap;
801
802         real_qp->qp_context = qp;
803
804         return qp;
805 }
806 symver(__ibv_create_qp_1_0, ibv_create_qp, IBVERBS_1.0);
807
808 int __ibv_query_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr,
809                        int attr_mask,
810                        struct ibv_qp_init_attr_1_0 *init_attr)
811 {
812         struct ibv_qp_init_attr real_init_attr;
813         int ret;
814
815         ret = ibv_query_qp(qp->real_qp, attr, attr_mask, &real_init_attr);
816         if (ret)
817                 return ret;
818
819         init_attr->qp_context = qp->qp_context;
820         init_attr->send_cq    = real_init_attr.send_cq->cq_context;
821         init_attr->recv_cq    = real_init_attr.recv_cq->cq_context;
822         init_attr->srq        = real_init_attr.srq->srq_context;
823         init_attr->qp_type    = real_init_attr.qp_type;
824         init_attr->cap        = real_init_attr.cap;
825         init_attr->sq_sig_all = real_init_attr.sq_sig_all;
826
827         return 0;
828 }
829 symver(__ibv_query_qp_1_0, ibv_query_qp, IBVERBS_1.0);
830
831 int __ibv_modify_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr,
832                         int attr_mask)
833 {
834         return ibv_modify_qp(qp->real_qp, attr, attr_mask);
835 }
836 symver(__ibv_modify_qp_1_0, ibv_modify_qp, IBVERBS_1.0);
837
838 int __ibv_destroy_qp_1_0(struct ibv_qp_1_0 *qp)
839 {
840         int ret;
841
842         ret = ibv_destroy_qp(qp->real_qp);
843         if (ret)
844                 return ret;
845
846         free(qp);
847         return 0;
848 }
849 symver(__ibv_destroy_qp_1_0, ibv_destroy_qp, IBVERBS_1.0);
850
851 struct ibv_ah_1_0 *__ibv_create_ah_1_0(struct ibv_pd_1_0 *pd,
852                                        struct ibv_ah_attr *attr)
853 {
854         struct ibv_ah *real_ah;
855         struct ibv_ah_1_0 *ah;
856
857         ah = malloc(sizeof *ah);
858         if (!ah)
859                 return NULL;
860
861         real_ah = ibv_create_ah(pd->real_pd, attr);
862         if (!real_ah) {
863                 free(ah);
864                 return NULL;
865         }
866
867         ah->context = pd->context;
868         ah->pd      = pd;
869         ah->real_ah = real_ah;
870
871         return ah;
872 }
873 symver(__ibv_create_ah_1_0, ibv_create_ah, IBVERBS_1.0);
874
875 int __ibv_destroy_ah_1_0(struct ibv_ah_1_0 *ah)
876 {
877         int ret;
878
879         ret = ibv_destroy_ah(ah->real_ah);
880         if (ret)
881                 return ret;
882
883         free(ah);
884         return 0;
885 }
886 symver(__ibv_destroy_ah_1_0, ibv_destroy_ah, IBVERBS_1.0);
887
888 int __ibv_attach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid, uint16_t lid)
889 {
890         return ibv_attach_mcast(qp->real_qp, gid, lid);
891 }
892 symver(__ibv_attach_mcast_1_0, ibv_attach_mcast, IBVERBS_1.0);
893
894 int __ibv_detach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid, uint16_t lid)
895 {
896         return ibv_detach_mcast(qp->real_qp, gid, lid);
897 }
898 symver(__ibv_detach_mcast_1_0, ibv_detach_mcast, IBVERBS_1.0);