]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ofed/libibverbs/compat-1_0.c
Upgrade to OpenSSH 7.6p1. This will be followed shortly by 7.7p1.
[FreeBSD/FreeBSD.git] / contrib / ofed / libibverbs / 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 #include <config.h>
34
35 #include <string.h>
36 #include <stddef.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <alloca.h>
40
41 #include "ibverbs.h"
42
43 struct ibv_pd_1_0 {
44         struct ibv_context_1_0 *context;
45         uint32_t                handle;
46
47         struct ibv_pd          *real_pd;
48 };
49
50 struct ibv_mr_1_0 {
51         struct ibv_context_1_0 *context;
52         struct ibv_pd_1_0      *pd;
53         uint32_t                handle;
54         uint32_t                lkey;
55         uint32_t                rkey;
56
57         struct ibv_mr          *real_mr;
58 };
59
60 struct ibv_srq_1_0 {
61         struct ibv_context_1_0 *context;
62         void                   *srq_context;
63         struct ibv_pd_1_0      *pd;
64         uint32_t                handle;
65
66         pthread_mutex_t         mutex;
67         pthread_cond_t          cond;
68         uint32_t                events_completed;
69
70         struct ibv_srq         *real_srq;
71 };
72
73 struct ibv_qp_init_attr_1_0 {
74         void                   *qp_context;
75         struct ibv_cq_1_0      *send_cq;
76         struct ibv_cq_1_0      *recv_cq;
77         struct ibv_srq_1_0     *srq;
78         struct ibv_qp_cap       cap;
79         enum ibv_qp_type        qp_type;
80         int                     sq_sig_all;
81 };
82
83 struct ibv_send_wr_1_0 {
84         struct ibv_send_wr_1_0 *next;
85         uint64_t                wr_id;
86         struct ibv_sge         *sg_list;
87         int                     num_sge;
88         enum ibv_wr_opcode      opcode;
89         int                     send_flags;
90         __be32                  imm_data;
91         union {
92                 struct {
93                         uint64_t        remote_addr;
94                         uint32_t        rkey;
95                 } rdma;
96                 struct {
97                         uint64_t        remote_addr;
98                         uint64_t        compare_add;
99                         uint64_t        swap;
100                         uint32_t        rkey;
101                 } atomic;
102                 struct {
103                         struct ibv_ah_1_0 *ah;
104                         uint32_t        remote_qpn;
105                         uint32_t        remote_qkey;
106                 } ud;
107         } wr;
108 };
109
110 struct ibv_recv_wr_1_0 {
111         struct ibv_recv_wr_1_0 *next;
112         uint64_t                wr_id;
113         struct ibv_sge         *sg_list;
114         int                     num_sge;
115 };
116
117 struct ibv_qp_1_0 {
118         struct ibv_context_1_0 *context;
119         void                   *qp_context;
120         struct ibv_pd_1_0      *pd;
121         struct ibv_cq_1_0      *send_cq;
122         struct ibv_cq_1_0      *recv_cq;
123         struct ibv_srq_1_0     *srq;
124         uint32_t                handle;
125         uint32_t                qp_num;
126         enum ibv_qp_state       state;
127         enum ibv_qp_type        qp_type;
128
129         pthread_mutex_t         mutex;
130         pthread_cond_t          cond;
131         uint32_t                events_completed;
132
133         struct ibv_qp          *real_qp;
134 };
135
136 struct ibv_cq_1_0 {
137         struct ibv_context_1_0 *context;
138         void                   *cq_context;
139         uint32_t                handle;
140         int                     cqe;
141
142         pthread_mutex_t         mutex;
143         pthread_cond_t          cond;
144         uint32_t                comp_events_completed;
145         uint32_t                async_events_completed;
146
147         struct ibv_cq          *real_cq;
148 };
149
150 struct ibv_ah_1_0 {
151         struct ibv_context_1_0 *context;
152         struct ibv_pd_1_0      *pd;
153         uint32_t                handle;
154
155         struct ibv_ah          *real_ah;
156 };
157
158 struct ibv_device_1_0 {
159         void                   *obsolete_sysfs_dev;
160         void                   *obsolete_sysfs_ibdev;
161         struct ibv_device      *real_device; /* was obsolete driver member */
162         struct _ibv_device_ops  _ops;
163 };
164
165 struct ibv_context_ops_1_0 {
166         int                     (*query_device)(struct ibv_context *context,
167                                               struct ibv_device_attr *device_attr);
168         int                     (*query_port)(struct ibv_context *context, uint8_t port_num,
169                                               struct ibv_port_attr *port_attr);
170         struct ibv_pd *         (*alloc_pd)(struct ibv_context *context);
171         int                     (*dealloc_pd)(struct ibv_pd *pd);
172         struct ibv_mr *         (*reg_mr)(struct ibv_pd *pd, void *addr, size_t length,
173                                           int access);
174         int                     (*dereg_mr)(struct ibv_mr *mr);
175         struct ibv_cq *         (*create_cq)(struct ibv_context *context, int cqe,
176                                              struct ibv_comp_channel *channel,
177                                              int comp_vector);
178         int                     (*poll_cq)(struct ibv_cq_1_0 *cq, int num_entries,
179                                            struct ibv_wc *wc);
180         int                     (*req_notify_cq)(struct ibv_cq_1_0 *cq,
181                                                  int solicited_only);
182         void                    (*cq_event)(struct ibv_cq *cq);
183         int                     (*resize_cq)(struct ibv_cq *cq, int cqe);
184         int                     (*destroy_cq)(struct ibv_cq *cq);
185         struct ibv_srq *        (*create_srq)(struct ibv_pd *pd,
186                                               struct ibv_srq_init_attr *srq_init_attr);
187         int                     (*modify_srq)(struct ibv_srq *srq,
188                                               struct ibv_srq_attr *srq_attr,
189                                               int srq_attr_mask);
190         int                     (*query_srq)(struct ibv_srq *srq,
191                                              struct ibv_srq_attr *srq_attr);
192         int                     (*destroy_srq)(struct ibv_srq *srq);
193         int                     (*post_srq_recv)(struct ibv_srq_1_0 *srq,
194                                                  struct ibv_recv_wr_1_0 *recv_wr,
195                                                  struct ibv_recv_wr_1_0 **bad_recv_wr);
196         struct ibv_qp *         (*create_qp)(struct ibv_pd *pd, struct ibv_qp_init_attr *attr);
197         int                     (*query_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr,
198                                             int attr_mask,
199                                             struct ibv_qp_init_attr *init_attr);
200         int                     (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr,
201                                              int attr_mask);
202         int                     (*destroy_qp)(struct ibv_qp *qp);
203         int                     (*post_send)(struct ibv_qp_1_0 *qp,
204                                              struct ibv_send_wr_1_0 *wr,
205                                              struct ibv_send_wr_1_0 **bad_wr);
206         int                     (*post_recv)(struct ibv_qp_1_0 *qp,
207                                              struct ibv_recv_wr_1_0 *wr,
208                                              struct ibv_recv_wr_1_0 **bad_wr);
209         struct ibv_ah *         (*create_ah)(struct ibv_pd *pd, struct ibv_ah_attr *attr);
210         int                     (*destroy_ah)(struct ibv_ah *ah);
211         int                     (*attach_mcast)(struct ibv_qp *qp, union ibv_gid *gid,
212                                                 uint16_t lid);
213         int                     (*detach_mcast)(struct ibv_qp *qp, union ibv_gid *gid,
214                                                 uint16_t lid);
215 };
216
217 struct ibv_context_1_0 {
218         struct ibv_device_1_0          *device;
219         struct ibv_context_ops_1_0      ops;
220         int                             cmd_fd;
221         int                             async_fd;
222         int                             num_comp_vectors;
223
224         struct ibv_context             *real_context; /* was abi_compat member */
225 };
226
227 typedef struct ibv_device *(*ibv_driver_init_func_1_1)(const char *uverbs_sys_path,
228                                                        int abi_version);
229
230 /* Hack to avoid GCC's -Wmissing-prototypes and the similar error from sparse
231    with these prototypes. Symbol versionining requires the goofy names, the
232    prototype must match the version in the historical 1.0 verbs.h.
233  */
234 struct ibv_device_1_0 **__ibv_get_device_list_1_0(int *num);
235 void __ibv_free_device_list_1_0(struct ibv_device_1_0 **list);
236 const char *__ibv_get_device_name_1_0(struct ibv_device_1_0 *device);
237 __be64 __ibv_get_device_guid_1_0(struct ibv_device_1_0 *device);
238 struct ibv_context_1_0 *__ibv_open_device_1_0(struct ibv_device_1_0 *device);
239 int __ibv_close_device_1_0(struct ibv_context_1_0 *context);
240 int __ibv_get_async_event_1_0(struct ibv_context_1_0 *context,
241                               struct ibv_async_event *event);
242 void __ibv_ack_async_event_1_0(struct ibv_async_event *event);
243 int __ibv_query_device_1_0(struct ibv_context_1_0 *context,
244                            struct ibv_device_attr *device_attr);
245 int __ibv_query_port_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
246                          struct ibv_port_attr *port_attr);
247 int __ibv_query_gid_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
248                         int index, union ibv_gid *gid);
249 int __ibv_query_pkey_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
250                          int index, __be16 *pkey);
251 struct ibv_pd_1_0 *__ibv_alloc_pd_1_0(struct ibv_context_1_0 *context);
252 int __ibv_dealloc_pd_1_0(struct ibv_pd_1_0 *pd);
253 struct ibv_mr_1_0 *__ibv_reg_mr_1_0(struct ibv_pd_1_0 *pd, void *addr,
254                                     size_t length, int access);
255 int __ibv_dereg_mr_1_0(struct ibv_mr_1_0 *mr);
256 struct ibv_cq_1_0 *__ibv_create_cq_1_0(struct ibv_context_1_0 *context, int cqe,
257                                        void *cq_context,
258                                        struct ibv_comp_channel *channel,
259                                        int comp_vector);
260 int __ibv_resize_cq_1_0(struct ibv_cq_1_0 *cq, int cqe);
261 int __ibv_destroy_cq_1_0(struct ibv_cq_1_0 *cq);
262 int __ibv_get_cq_event_1_0(struct ibv_comp_channel *channel,
263                            struct ibv_cq_1_0 **cq, void **cq_context);
264 void __ibv_ack_cq_events_1_0(struct ibv_cq_1_0 *cq, unsigned int nevents);
265 struct ibv_srq_1_0 *
266 __ibv_create_srq_1_0(struct ibv_pd_1_0 *pd,
267                      struct ibv_srq_init_attr *srq_init_attr);
268 int __ibv_modify_srq_1_0(struct ibv_srq_1_0 *srq, struct ibv_srq_attr *srq_attr,
269                          int srq_attr_mask);
270 int __ibv_query_srq_1_0(struct ibv_srq_1_0 *srq, struct ibv_srq_attr *srq_attr);
271 int __ibv_destroy_srq_1_0(struct ibv_srq_1_0 *srq);
272 struct ibv_qp_1_0 *
273 __ibv_create_qp_1_0(struct ibv_pd_1_0 *pd,
274                     struct ibv_qp_init_attr_1_0 *qp_init_attr);
275 int __ibv_query_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr,
276                        int attr_mask, struct ibv_qp_init_attr_1_0 *init_attr);
277 int __ibv_modify_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr,
278                         int attr_mask);
279 int __ibv_destroy_qp_1_0(struct ibv_qp_1_0 *qp);
280 struct ibv_ah_1_0 *__ibv_create_ah_1_0(struct ibv_pd_1_0 *pd,
281                                        struct ibv_ah_attr *attr);
282 int __ibv_destroy_ah_1_0(struct ibv_ah_1_0 *ah);
283 int __ibv_attach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid,
284                            uint16_t lid);
285 int __ibv_detach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid,
286                            uint16_t lid);
287 void __ibv_register_driver_1_1(const char *name,
288                                ibv_driver_init_func_1_1 init_func);
289
290 struct ibv_device_1_0 **__ibv_get_device_list_1_0(int *num)
291 {
292         struct ibv_device **real_list;
293         struct ibv_device_1_0 **l;
294         int i, n;
295
296         real_list = ibv_get_device_list(&n);
297         if (!real_list)
298                 return NULL;
299
300         l = calloc(n + 2, sizeof (struct ibv_device_1_0 *));
301         if (!l)
302                 goto free_device_list;
303
304         l[0] = (void *) real_list;
305
306         for (i = 0; i < n; ++i) {
307                 l[i + 1] = calloc(1, sizeof (struct ibv_device_1_0));
308                 if (!l[i + 1])
309                         goto fail;
310                 l[i + 1]->real_device = real_list[i];
311         }
312
313         if (num)
314                 *num = n;
315
316         return l + 1;
317
318 fail:
319         for (i = 1; i <= n; ++i)
320                 if (l[i])
321                         free(l[i]);
322         free(l);
323
324 free_device_list:
325         ibv_free_device_list(real_list);
326         return NULL;
327 }
328 symver(__ibv_get_device_list_1_0, ibv_get_device_list, IBVERBS_1.0);
329
330 void __ibv_free_device_list_1_0(struct ibv_device_1_0 **list)
331 {
332         struct ibv_device_1_0 **l = list;
333
334         while (*l) {
335                 free(*l);
336                 ++l;
337         }
338
339         ibv_free_device_list((void *) list[-1]);
340         free(list - 1);
341 }
342 symver(__ibv_free_device_list_1_0, ibv_free_device_list, IBVERBS_1.0);
343
344 const char *__ibv_get_device_name_1_0(struct ibv_device_1_0 *device)
345 {
346         return ibv_get_device_name(device->real_device);
347 }
348 symver(__ibv_get_device_name_1_0, ibv_get_device_name, IBVERBS_1.0);
349
350 __be64 __ibv_get_device_guid_1_0(struct ibv_device_1_0 *device)
351 {
352         return ibv_get_device_guid(device->real_device);
353 }
354 symver(__ibv_get_device_guid_1_0, ibv_get_device_guid, IBVERBS_1.0);
355
356 static int poll_cq_wrapper_1_0(struct ibv_cq_1_0 *cq, int num_entries,
357                                struct ibv_wc *wc)
358 {
359         return cq->context->real_context->ops.poll_cq(cq->real_cq, num_entries, wc);
360 }
361
362 static int req_notify_cq_wrapper_1_0(struct ibv_cq_1_0 *cq, int sol_only)
363 {
364         return cq->context->real_context->ops.req_notify_cq(cq->real_cq, sol_only);
365 }
366
367 static int post_srq_recv_wrapper_1_0(struct ibv_srq_1_0 *srq, struct ibv_recv_wr_1_0 *wr,
368                                  struct ibv_recv_wr_1_0 **bad_wr)
369 {
370         struct ibv_recv_wr_1_0 *w;
371         struct ibv_recv_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr;
372         int ret;
373
374         for (w = wr; w; w = w->next) {
375                 real_wr = alloca(sizeof *real_wr);
376                 real_wr->wr_id   = w->wr_id;
377                 real_wr->sg_list = w->sg_list;
378                 real_wr->num_sge = w->num_sge;
379                 real_wr->next    = NULL;
380                 if (tail_wr)
381                         tail_wr->next = real_wr;
382                 else
383                         head_wr = real_wr;
384
385                 tail_wr = real_wr;
386         }
387
388         ret = srq->context->real_context->ops.post_srq_recv(srq->real_srq, head_wr,
389                                                             &real_bad_wr);
390
391         if (ret) {
392                 for (real_wr = head_wr, w = wr;
393                      real_wr;
394                      real_wr = real_wr->next, w = w->next)
395                         if (real_wr == real_bad_wr) {
396                                 *bad_wr = w;
397                                 break;
398                         }
399         }
400
401         return ret;
402 }
403
404 static int post_send_wrapper_1_0(struct ibv_qp_1_0 *qp, struct ibv_send_wr_1_0 *wr,
405                                  struct ibv_send_wr_1_0 **bad_wr)
406 {
407         struct ibv_send_wr_1_0 *w;
408         struct ibv_send_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr;
409         int is_ud = qp->qp_type == IBV_QPT_UD;
410         int ret;
411
412         for (w = wr; w; w = w->next) {
413                 real_wr = alloca(sizeof *real_wr);
414                 real_wr->wr_id = w->wr_id;
415                 real_wr->next  = NULL;
416
417 #define TEST_SIZE_2_POINT(f1, f2)                                       \
418                 ((offsetof(struct ibv_send_wr, f1) - offsetof(struct ibv_send_wr, f2)) \
419                  == offsetof(struct ibv_send_wr_1_0, f1) - offsetof(struct ibv_send_wr_1_0, f2))
420 #define TEST_SIZE_TO_END(f1)                                        \
421                 ((sizeof(struct ibv_send_wr) - offsetof(struct ibv_send_wr, f1)) == \
422                  (sizeof(struct ibv_send_wr_1_0) - offsetof(struct ibv_send_wr_1_0, f1)))
423
424                 if (TEST_SIZE_TO_END (sg_list))
425                         memcpy(&real_wr->sg_list, &w->sg_list, sizeof *real_wr
426                                - offsetof(struct ibv_send_wr, sg_list));
427                 else if (TEST_SIZE_2_POINT (imm_data, sg_list) &&
428                          TEST_SIZE_TO_END (wr)) {
429                         /* we have alignment up to wr, but padding between
430                          * imm_data and wr, and we know wr itself is the
431                          * same size */
432                         memcpy(&real_wr->sg_list, &w->sg_list,
433                                offsetof(struct ibv_send_wr, imm_data) -
434                                offsetof(struct ibv_send_wr, sg_list) +
435                                sizeof real_wr->imm_data);
436                         memcpy(&real_wr->wr, &w->wr, sizeof real_wr->wr);
437                 } else {
438                         real_wr->sg_list = w->sg_list;
439                         real_wr->num_sge = w->num_sge;
440                         real_wr->opcode = w->opcode;
441                         real_wr->send_flags = w->send_flags;
442                         real_wr->imm_data = w->imm_data;
443                         if (TEST_SIZE_TO_END (wr))
444                                 memcpy(&real_wr->wr, &w->wr,
445                                        sizeof real_wr->wr);
446                         else {
447                                 real_wr->wr.atomic.remote_addr =
448                                         w->wr.atomic.remote_addr;
449                                 real_wr->wr.atomic.compare_add =
450                                         w->wr.atomic.compare_add;
451                                 real_wr->wr.atomic.swap =
452                                         w->wr.atomic.swap;
453                                 real_wr->wr.atomic.rkey =
454                                         w->wr.atomic.rkey;
455                         }
456                 }
457
458                 if (is_ud)
459                         real_wr->wr.ud.ah = w->wr.ud.ah->real_ah;
460
461                 if (tail_wr)
462                         tail_wr->next = real_wr;
463                 else
464                         head_wr = real_wr;
465
466                 tail_wr = real_wr;
467         }
468
469         ret = qp->context->real_context->ops.post_send(qp->real_qp, head_wr,
470                                                        &real_bad_wr);
471
472         if (ret) {
473                 for (real_wr = head_wr, w = wr;
474                      real_wr;
475                      real_wr = real_wr->next, w = w->next)
476                         if (real_wr == real_bad_wr) {
477                                 *bad_wr = w;
478                                 break;
479                         }
480         }
481
482         return ret;
483 }
484
485 static int post_recv_wrapper_1_0(struct ibv_qp_1_0 *qp, struct ibv_recv_wr_1_0 *wr,
486                                  struct ibv_recv_wr_1_0 **bad_wr)
487 {
488         struct ibv_recv_wr_1_0 *w;
489         struct ibv_recv_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr;
490         int ret;
491
492         for (w = wr; w; w = w->next) {
493                 real_wr = alloca(sizeof *real_wr);
494                 real_wr->wr_id   = w->wr_id;
495                 real_wr->sg_list = w->sg_list;
496                 real_wr->num_sge = w->num_sge;
497                 real_wr->next    = NULL;
498                 if (tail_wr)
499                         tail_wr->next = real_wr;
500                 else
501                         head_wr = real_wr;
502
503                 tail_wr = real_wr;
504         }
505
506         ret = qp->context->real_context->ops.post_recv(qp->real_qp, head_wr,
507                                                        &real_bad_wr);
508
509         if (ret) {
510                 for (real_wr = head_wr, w = wr;
511                      real_wr;
512                      real_wr = real_wr->next, w = w->next)
513                         if (real_wr == real_bad_wr) {
514                                 *bad_wr = w;
515                                 break;
516                         }
517         }
518
519         return ret;
520 }
521
522 struct ibv_context_1_0 *__ibv_open_device_1_0(struct ibv_device_1_0 *device)
523 {
524         struct ibv_context     *real_ctx;
525         struct ibv_context_1_0 *ctx;
526
527         ctx = malloc(sizeof *ctx);
528         if (!ctx)
529                 return NULL;
530
531         real_ctx = ibv_open_device(device->real_device);
532         if (!real_ctx) {
533                 free(ctx);
534                 return NULL;
535         }
536
537         ctx->device       = device;
538         ctx->real_context = real_ctx;
539
540         ctx->ops.poll_cq       = poll_cq_wrapper_1_0;
541         ctx->ops.req_notify_cq = req_notify_cq_wrapper_1_0;
542         ctx->ops.post_send     = post_send_wrapper_1_0;
543         ctx->ops.post_recv     = post_recv_wrapper_1_0;
544         ctx->ops.post_srq_recv = post_srq_recv_wrapper_1_0;
545
546         return ctx;
547 }
548 symver(__ibv_open_device_1_0, ibv_open_device, IBVERBS_1.0);
549
550 int __ibv_close_device_1_0(struct ibv_context_1_0 *context)
551 {
552         int ret;
553
554         ret = ibv_close_device(context->real_context);
555         if (ret)
556                 return ret;
557
558         free(context);
559         return 0;
560 }
561 symver(__ibv_close_device_1_0, ibv_close_device, IBVERBS_1.0);
562
563 int __ibv_get_async_event_1_0(struct ibv_context_1_0 *context,
564                               struct ibv_async_event *event)
565 {
566         int ret;
567
568         ret = ibv_get_async_event(context->real_context, event);
569         if (ret)
570                 return ret;
571
572         switch (event->event_type) {
573         case IBV_EVENT_CQ_ERR:
574                 event->element.cq = event->element.cq->cq_context;
575                 break;
576
577         case IBV_EVENT_QP_FATAL:
578         case IBV_EVENT_QP_REQ_ERR:
579         case IBV_EVENT_QP_ACCESS_ERR:
580         case IBV_EVENT_COMM_EST:
581         case IBV_EVENT_SQ_DRAINED:
582         case IBV_EVENT_PATH_MIG:
583         case IBV_EVENT_PATH_MIG_ERR:
584         case IBV_EVENT_QP_LAST_WQE_REACHED:
585                 event->element.qp = event->element.qp->qp_context;
586                 break;
587
588         case IBV_EVENT_SRQ_ERR:
589         case IBV_EVENT_SRQ_LIMIT_REACHED:
590                 event->element.srq = event->element.srq->srq_context;
591                 break;
592
593         default:
594                 break;
595         }
596
597         return ret;
598 }
599 symver(__ibv_get_async_event_1_0, ibv_get_async_event, IBVERBS_1.0);
600
601 void __ibv_ack_async_event_1_0(struct ibv_async_event *event)
602 {
603         struct ibv_async_event real_event = *event;
604
605         switch (event->event_type) {
606         case IBV_EVENT_CQ_ERR:
607                 real_event.element.cq =
608                         ((struct ibv_cq_1_0 *) event->element.cq)->real_cq;
609                 break;
610
611         case IBV_EVENT_QP_FATAL:
612         case IBV_EVENT_QP_REQ_ERR:
613         case IBV_EVENT_QP_ACCESS_ERR:
614         case IBV_EVENT_COMM_EST:
615         case IBV_EVENT_SQ_DRAINED:
616         case IBV_EVENT_PATH_MIG:
617         case IBV_EVENT_PATH_MIG_ERR:
618         case IBV_EVENT_QP_LAST_WQE_REACHED:
619                 real_event.element.qp =
620                         ((struct ibv_qp_1_0 *) event->element.qp)->real_qp;
621                 break;
622
623         case IBV_EVENT_SRQ_ERR:
624         case IBV_EVENT_SRQ_LIMIT_REACHED:
625                 real_event.element.srq =
626                         ((struct ibv_srq_1_0 *) event->element.srq)->real_srq;
627                 break;
628
629         default:
630                 break;
631         }
632
633         ibv_ack_async_event(&real_event);
634 }
635 symver(__ibv_ack_async_event_1_0, ibv_ack_async_event, IBVERBS_1.0);
636
637 int __ibv_query_device_1_0(struct ibv_context_1_0 *context,
638                            struct ibv_device_attr *device_attr)
639 {
640         return ibv_query_device(context->real_context, device_attr);
641 }
642 symver(__ibv_query_device_1_0, ibv_query_device, IBVERBS_1.0);
643
644 int __ibv_query_port_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
645                          struct ibv_port_attr *port_attr)
646 {
647         return ibv_query_port(context->real_context, port_num, port_attr);
648 }
649 symver(__ibv_query_port_1_0, ibv_query_port, IBVERBS_1.0);
650
651 int __ibv_query_gid_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
652                         int index, union ibv_gid *gid)
653 {
654         return ibv_query_gid(context->real_context, port_num, index, gid);
655 }
656 symver(__ibv_query_gid_1_0, ibv_query_gid, IBVERBS_1.0);
657
658 int __ibv_query_pkey_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
659                          int index, __be16 *pkey)
660 {
661         return ibv_query_pkey(context->real_context, port_num, index, pkey);
662 }
663 symver(__ibv_query_pkey_1_0, ibv_query_pkey, IBVERBS_1.0);
664
665 struct ibv_pd_1_0 *__ibv_alloc_pd_1_0(struct ibv_context_1_0 *context)
666 {
667         struct ibv_pd *real_pd;
668         struct ibv_pd_1_0 *pd;
669
670         pd = malloc(sizeof *pd);
671         if (!pd)
672                 return NULL;
673
674         real_pd = ibv_alloc_pd(context->real_context);
675         if (!real_pd) {
676                 free(pd);
677                 return NULL;
678         }
679
680         pd->context = context;
681         pd->real_pd = real_pd;
682
683         return pd;
684 }
685 symver(__ibv_alloc_pd_1_0, ibv_alloc_pd, IBVERBS_1.0);
686
687 int __ibv_dealloc_pd_1_0(struct ibv_pd_1_0 *pd)
688 {
689         int ret;
690
691         ret = ibv_dealloc_pd(pd->real_pd);
692         if (ret)
693                 return ret;
694
695         free(pd);
696         return 0;
697 }
698 symver(__ibv_dealloc_pd_1_0, ibv_dealloc_pd, IBVERBS_1.0);
699
700 struct ibv_mr_1_0 *__ibv_reg_mr_1_0(struct ibv_pd_1_0 *pd, void *addr,
701                                     size_t length, int access)
702 {
703         struct ibv_mr *real_mr;
704         struct ibv_mr_1_0 *mr;
705
706         mr = malloc(sizeof *mr);
707         if (!mr)
708                 return NULL;
709
710         real_mr = ibv_reg_mr(pd->real_pd, addr, length, access);
711         if (!real_mr) {
712                 free(mr);
713                 return NULL;
714         }
715
716         mr->context = pd->context;
717         mr->pd      = pd;
718         mr->lkey    = real_mr->lkey;
719         mr->rkey    = real_mr->rkey;
720         mr->real_mr = real_mr;
721
722         return mr;
723 }
724 symver(__ibv_reg_mr_1_0, ibv_reg_mr, IBVERBS_1.0);
725
726 int __ibv_dereg_mr_1_0(struct ibv_mr_1_0 *mr)
727 {
728         int ret;
729
730         ret = ibv_dereg_mr(mr->real_mr);
731         if (ret)
732                 return ret;
733
734         free(mr);
735         return 0;
736 }
737 symver(__ibv_dereg_mr_1_0, ibv_dereg_mr, IBVERBS_1.0);
738
739 struct ibv_cq_1_0 *__ibv_create_cq_1_0(struct ibv_context_1_0 *context, int cqe,
740                                        void *cq_context,
741                                        struct ibv_comp_channel *channel,
742                                        int comp_vector)
743 {
744         struct ibv_cq *real_cq;
745         struct ibv_cq_1_0 *cq;
746
747         cq = malloc(sizeof *cq);
748         if (!cq)
749                 return NULL;
750
751         real_cq = ibv_create_cq(context->real_context, cqe, cq_context,
752                                 channel, comp_vector);
753         if (!real_cq) {
754                 free(cq);
755                 return NULL;
756         }
757
758         cq->context    = context;
759         cq->cq_context = cq_context;
760         cq->cqe        = cqe;
761         cq->real_cq    = real_cq;
762
763         real_cq->cq_context = cq;
764
765         return cq;
766 }
767 symver(__ibv_create_cq_1_0, ibv_create_cq, IBVERBS_1.0);
768
769 int __ibv_resize_cq_1_0(struct ibv_cq_1_0 *cq, int cqe)
770 {
771         return ibv_resize_cq(cq->real_cq, cqe);
772 }
773 symver(__ibv_resize_cq_1_0, ibv_resize_cq, IBVERBS_1.0);
774
775 int __ibv_destroy_cq_1_0(struct ibv_cq_1_0 *cq)
776 {
777         int ret;
778
779         ret = ibv_destroy_cq(cq->real_cq);
780         if (ret)
781                 return ret;
782
783         free(cq);
784         return 0;
785 }
786 symver(__ibv_destroy_cq_1_0, ibv_destroy_cq, IBVERBS_1.0);
787
788 int __ibv_get_cq_event_1_0(struct ibv_comp_channel *channel,
789                            struct ibv_cq_1_0 **cq, void **cq_context)
790 {
791         struct ibv_cq *real_cq;
792         void *cq_ptr;
793         int ret;
794
795         ret = ibv_get_cq_event(channel, &real_cq, &cq_ptr);
796         if (ret)
797                 return ret;
798
799         *cq         = cq_ptr;
800         *cq_context = (*cq)->cq_context;
801
802         return 0;
803 }
804 symver(__ibv_get_cq_event_1_0, ibv_get_cq_event, IBVERBS_1.0);
805
806 void __ibv_ack_cq_events_1_0(struct ibv_cq_1_0 *cq, unsigned int nevents)
807 {
808         ibv_ack_cq_events(cq->real_cq, nevents);
809 }
810 symver(__ibv_ack_cq_events_1_0, ibv_ack_cq_events, IBVERBS_1.0);
811
812 struct ibv_srq_1_0 *__ibv_create_srq_1_0(struct ibv_pd_1_0 *pd,
813                                          struct ibv_srq_init_attr *srq_init_attr)
814 {
815         struct ibv_srq *real_srq;
816         struct ibv_srq_1_0 *srq;
817
818         srq = malloc(sizeof *srq);
819         if (!srq)
820                 return NULL;
821
822         real_srq = ibv_create_srq(pd->real_pd, srq_init_attr);
823         if (!real_srq) {
824                 free(srq);
825                 return NULL;
826         }
827
828         srq->context     = pd->context;
829         srq->srq_context = srq_init_attr->srq_context;
830         srq->pd          = pd;
831         srq->real_srq    = real_srq;
832
833         real_srq->srq_context = srq;
834
835         return srq;
836 }
837 symver(__ibv_create_srq_1_0, ibv_create_srq, IBVERBS_1.0);
838
839 int __ibv_modify_srq_1_0(struct ibv_srq_1_0 *srq,
840                          struct ibv_srq_attr *srq_attr,
841                          int srq_attr_mask)
842 {
843         return ibv_modify_srq(srq->real_srq, srq_attr, srq_attr_mask);
844 }
845 symver(__ibv_modify_srq_1_0, ibv_modify_srq, IBVERBS_1.0);
846
847 int __ibv_query_srq_1_0(struct ibv_srq_1_0 *srq, struct ibv_srq_attr *srq_attr)
848 {
849         return ibv_query_srq(srq->real_srq, srq_attr);
850 }
851 symver(__ibv_query_srq_1_0, ibv_query_srq, IBVERBS_1.0);
852
853 int __ibv_destroy_srq_1_0(struct ibv_srq_1_0 *srq)
854 {
855         int ret;
856
857         ret = ibv_destroy_srq(srq->real_srq);
858         if (ret)
859                 return ret;
860
861         free(srq);
862         return 0;
863 }
864 symver(__ibv_destroy_srq_1_0, ibv_destroy_srq, IBVERBS_1.0);
865
866 struct ibv_qp_1_0 *__ibv_create_qp_1_0(struct ibv_pd_1_0 *pd,
867                                        struct ibv_qp_init_attr_1_0 *qp_init_attr)
868 {
869         struct ibv_qp *real_qp;
870         struct ibv_qp_1_0 *qp;
871         struct ibv_qp_init_attr real_init_attr;
872
873         qp = malloc(sizeof *qp);
874         if (!qp)
875                 return NULL;
876
877         real_init_attr.qp_context = qp_init_attr->qp_context;
878         real_init_attr.send_cq    = qp_init_attr->send_cq->real_cq;
879         real_init_attr.recv_cq    = qp_init_attr->recv_cq->real_cq;
880         real_init_attr.srq        = qp_init_attr->srq ?
881                 qp_init_attr->srq->real_srq : NULL;
882         real_init_attr.cap        = qp_init_attr->cap;
883         real_init_attr.qp_type    = qp_init_attr->qp_type;
884         real_init_attr.sq_sig_all = qp_init_attr->sq_sig_all;
885
886         real_qp = ibv_create_qp(pd->real_pd, &real_init_attr);
887         if (!real_qp) {
888                 free(qp);
889                 return NULL;
890         }
891
892         qp->context    = pd->context;
893         qp->qp_context = qp_init_attr->qp_context;
894         qp->pd         = pd;
895         qp->send_cq    = qp_init_attr->send_cq;
896         qp->recv_cq    = qp_init_attr->recv_cq;
897         qp->srq        = qp_init_attr->srq;
898         qp->qp_type    = qp_init_attr->qp_type;
899         qp->qp_num     = real_qp->qp_num;
900         qp->real_qp    = real_qp;
901
902         qp_init_attr->cap = real_init_attr.cap;
903
904         real_qp->qp_context = qp;
905
906         return qp;
907 }
908 symver(__ibv_create_qp_1_0, ibv_create_qp, IBVERBS_1.0);
909
910 int __ibv_query_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr,
911                        int attr_mask,
912                        struct ibv_qp_init_attr_1_0 *init_attr)
913 {
914         struct ibv_qp_init_attr real_init_attr;
915         int ret;
916
917         ret = ibv_query_qp(qp->real_qp, attr, attr_mask, &real_init_attr);
918         if (ret)
919                 return ret;
920
921         init_attr->qp_context = qp->qp_context;
922         init_attr->send_cq    = real_init_attr.send_cq->cq_context;
923         init_attr->recv_cq    = real_init_attr.recv_cq->cq_context;
924         init_attr->srq        = real_init_attr.srq->srq_context;
925         init_attr->qp_type    = real_init_attr.qp_type;
926         init_attr->cap        = real_init_attr.cap;
927         init_attr->sq_sig_all = real_init_attr.sq_sig_all;
928
929         return 0;
930 }
931 symver(__ibv_query_qp_1_0, ibv_query_qp, IBVERBS_1.0);
932
933 int __ibv_modify_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr,
934                         int attr_mask)
935 {
936         return ibv_modify_qp(qp->real_qp, attr, attr_mask);
937 }
938 symver(__ibv_modify_qp_1_0, ibv_modify_qp, IBVERBS_1.0);
939
940 int __ibv_destroy_qp_1_0(struct ibv_qp_1_0 *qp)
941 {
942         int ret;
943
944         ret = ibv_destroy_qp(qp->real_qp);
945         if (ret)
946                 return ret;
947
948         free(qp);
949         return 0;
950 }
951 symver(__ibv_destroy_qp_1_0, ibv_destroy_qp, IBVERBS_1.0);
952
953 struct ibv_ah_1_0 *__ibv_create_ah_1_0(struct ibv_pd_1_0 *pd,
954                                        struct ibv_ah_attr *attr)
955 {
956         struct ibv_ah *real_ah;
957         struct ibv_ah_1_0 *ah;
958
959         ah = malloc(sizeof *ah);
960         if (!ah)
961                 return NULL;
962
963         real_ah = ibv_create_ah(pd->real_pd, attr);
964         if (!real_ah) {
965                 free(ah);
966                 return NULL;
967         }
968
969         ah->context = pd->context;
970         ah->pd      = pd;
971         ah->real_ah = real_ah;
972
973         return ah;
974 }
975 symver(__ibv_create_ah_1_0, ibv_create_ah, IBVERBS_1.0);
976
977 int __ibv_destroy_ah_1_0(struct ibv_ah_1_0 *ah)
978 {
979         int ret;
980
981         ret = ibv_destroy_ah(ah->real_ah);
982         if (ret)
983                 return ret;
984
985         free(ah);
986         return 0;
987 }
988 symver(__ibv_destroy_ah_1_0, ibv_destroy_ah, IBVERBS_1.0);
989
990 int __ibv_attach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid, uint16_t lid)
991 {
992         return ibv_attach_mcast(qp->real_qp, gid, lid);
993 }
994 symver(__ibv_attach_mcast_1_0, ibv_attach_mcast, IBVERBS_1.0);
995
996 int __ibv_detach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid, uint16_t lid)
997 {
998         return ibv_detach_mcast(qp->real_qp, gid, lid);
999 }
1000 symver(__ibv_detach_mcast_1_0, ibv_detach_mcast, IBVERBS_1.0);
1001
1002 void __ibv_register_driver_1_1(const char *name, ibv_driver_init_func_1_1 init_func)
1003 {
1004         /* The driver interface is private as of rdma-core 13. This stub is
1005          * left to preserve dynamic-link compatibility with old libfabrics
1006          * usnic providers which use this function only to suppress a fprintf
1007          * in old versions of libibverbs. */
1008 }
1009 symver(__ibv_register_driver_1_1, ibv_register_driver, IBVERBS_1.1);