1219820Sjeff/* 2219820Sjeff * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. 3219820Sjeff * 4219820Sjeff * This software is available to you under a choice of one of two 5219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 6219820Sjeff * General Public License (GPL) Version 2, available from the file 7219820Sjeff * COPYING in the main directory of this source tree, or the 8219820Sjeff * OpenIB.org BSD license below: 9219820Sjeff * 10219820Sjeff * Redistribution and use in source and binary forms, with or 11219820Sjeff * without modification, are permitted provided that the following 12219820Sjeff * conditions are met: 13219820Sjeff * 14219820Sjeff * - Redistributions of source code must retain the above 15219820Sjeff * copyright notice, this list of conditions and the following 16219820Sjeff * disclaimer. 17219820Sjeff * 18219820Sjeff * - Redistributions in binary form must reproduce the above 19219820Sjeff * copyright notice, this list of conditions and the following 20219820Sjeff * disclaimer in the documentation and/or other materials 21219820Sjeff * provided with the distribution. 22219820Sjeff * 23219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30219820Sjeff * SOFTWARE. 31219820Sjeff */ 32219820Sjeff 33219820Sjeff#if HAVE_CONFIG_H 34219820Sjeff# include <config.h> 35219820Sjeff#endif /* HAVE_CONFIG_H */ 36219820Sjeff 37219820Sjeff#include <string.h> 38219820Sjeff#include <stddef.h> 39219820Sjeff#include <stdlib.h> 40219820Sjeff#include <unistd.h> 41219820Sjeff#include <alloca.h> 42219820Sjeff 43219820Sjeff#include "ibverbs.h" 44219820Sjeff 45219820Sjeffstruct ibv_pd_1_0 { 46219820Sjeff struct ibv_context_1_0 *context; 47219820Sjeff uint32_t handle; 48219820Sjeff 49219820Sjeff struct ibv_pd *real_pd; 50219820Sjeff}; 51219820Sjeff 52219820Sjeffstruct ibv_mr_1_0 { 53219820Sjeff struct ibv_context_1_0 *context; 54219820Sjeff struct ibv_pd_1_0 *pd; 55219820Sjeff uint32_t handle; 56219820Sjeff uint32_t lkey; 57219820Sjeff uint32_t rkey; 58219820Sjeff 59219820Sjeff struct ibv_mr *real_mr; 60219820Sjeff}; 61219820Sjeff 62219820Sjeffstruct ibv_srq_1_0 { 63219820Sjeff struct ibv_context_1_0 *context; 64219820Sjeff void *srq_context; 65219820Sjeff struct ibv_pd_1_0 *pd; 66219820Sjeff uint32_t handle; 67219820Sjeff 68219820Sjeff pthread_mutex_t mutex; 69219820Sjeff pthread_cond_t cond; 70219820Sjeff uint32_t events_completed; 71219820Sjeff 72219820Sjeff struct ibv_srq *real_srq; 73219820Sjeff}; 74219820Sjeff 75219820Sjeffstruct ibv_qp_init_attr_1_0 { 76219820Sjeff void *qp_context; 77219820Sjeff struct ibv_cq_1_0 *send_cq; 78219820Sjeff struct ibv_cq_1_0 *recv_cq; 79219820Sjeff struct ibv_srq_1_0 *srq; 80219820Sjeff struct ibv_qp_cap cap; 81219820Sjeff enum ibv_qp_type qp_type; 82219820Sjeff int sq_sig_all; 83219820Sjeff}; 84219820Sjeff 85219820Sjeffstruct ibv_send_wr_1_0 { 86219820Sjeff struct ibv_send_wr_1_0 *next; 87219820Sjeff uint64_t wr_id; 88219820Sjeff struct ibv_sge *sg_list; 89219820Sjeff int num_sge; 90219820Sjeff enum ibv_wr_opcode opcode; 91219820Sjeff int send_flags; 92219820Sjeff uint32_t imm_data; /* in network byte order */ 93219820Sjeff union { 94219820Sjeff struct { 95219820Sjeff uint64_t remote_addr; 96219820Sjeff uint32_t rkey; 97219820Sjeff } rdma; 98219820Sjeff struct { 99219820Sjeff uint64_t remote_addr; 100219820Sjeff uint64_t compare_add; 101219820Sjeff uint64_t swap; 102219820Sjeff uint32_t rkey; 103219820Sjeff } atomic; 104219820Sjeff struct { 105219820Sjeff struct ibv_ah_1_0 *ah; 106219820Sjeff uint32_t remote_qpn; 107219820Sjeff uint32_t remote_qkey; 108219820Sjeff } ud; 109219820Sjeff } wr; 110219820Sjeff}; 111219820Sjeff 112219820Sjeffstruct ibv_recv_wr_1_0 { 113219820Sjeff struct ibv_recv_wr_1_0 *next; 114219820Sjeff uint64_t wr_id; 115219820Sjeff struct ibv_sge *sg_list; 116219820Sjeff int num_sge; 117219820Sjeff}; 118219820Sjeff 119219820Sjeffstruct ibv_qp_1_0 { 120219820Sjeff struct ibv_context_1_0 *context; 121219820Sjeff void *qp_context; 122219820Sjeff struct ibv_pd_1_0 *pd; 123219820Sjeff struct ibv_cq_1_0 *send_cq; 124219820Sjeff struct ibv_cq_1_0 *recv_cq; 125219820Sjeff struct ibv_srq_1_0 *srq; 126219820Sjeff uint32_t handle; 127219820Sjeff uint32_t qp_num; 128219820Sjeff enum ibv_qp_state state; 129219820Sjeff enum ibv_qp_type qp_type; 130219820Sjeff 131219820Sjeff pthread_mutex_t mutex; 132219820Sjeff pthread_cond_t cond; 133219820Sjeff uint32_t events_completed; 134219820Sjeff 135219820Sjeff struct ibv_qp *real_qp; 136219820Sjeff}; 137219820Sjeff 138219820Sjeffstruct ibv_cq_1_0 { 139219820Sjeff struct ibv_context_1_0 *context; 140219820Sjeff void *cq_context; 141219820Sjeff uint32_t handle; 142219820Sjeff int cqe; 143219820Sjeff 144219820Sjeff pthread_mutex_t mutex; 145219820Sjeff pthread_cond_t cond; 146219820Sjeff uint32_t comp_events_completed; 147219820Sjeff uint32_t async_events_completed; 148219820Sjeff 149219820Sjeff struct ibv_cq *real_cq; 150219820Sjeff}; 151219820Sjeff 152219820Sjeffstruct ibv_ah_1_0 { 153219820Sjeff struct ibv_context_1_0 *context; 154219820Sjeff struct ibv_pd_1_0 *pd; 155219820Sjeff uint32_t handle; 156219820Sjeff 157219820Sjeff struct ibv_ah *real_ah; 158219820Sjeff}; 159219820Sjeff 160219820Sjeffstruct ibv_device_1_0 { 161219820Sjeff void *obsolete_sysfs_dev; 162219820Sjeff void *obsolete_sysfs_ibdev; 163219820Sjeff struct ibv_device *real_device; /* was obsolete driver member */ 164219820Sjeff struct ibv_device_ops ops; 165219820Sjeff}; 166219820Sjeff 167219820Sjeffstruct ibv_context_ops_1_0 { 168219820Sjeff int (*query_device)(struct ibv_context *context, 169219820Sjeff struct ibv_device_attr *device_attr); 170219820Sjeff int (*query_port)(struct ibv_context *context, uint8_t port_num, 171219820Sjeff struct ibv_port_attr *port_attr); 172219820Sjeff struct ibv_pd * (*alloc_pd)(struct ibv_context *context); 173219820Sjeff int (*dealloc_pd)(struct ibv_pd *pd); 174219820Sjeff struct ibv_mr * (*reg_mr)(struct ibv_pd *pd, void *addr, size_t length, 175219820Sjeff int access); 176219820Sjeff int (*dereg_mr)(struct ibv_mr *mr); 177219820Sjeff struct ibv_cq * (*create_cq)(struct ibv_context *context, int cqe, 178219820Sjeff struct ibv_comp_channel *channel, 179219820Sjeff int comp_vector); 180219820Sjeff int (*poll_cq)(struct ibv_cq_1_0 *cq, int num_entries, 181219820Sjeff struct ibv_wc *wc); 182219820Sjeff int (*req_notify_cq)(struct ibv_cq_1_0 *cq, 183219820Sjeff int solicited_only); 184219820Sjeff void (*cq_event)(struct ibv_cq *cq); 185219820Sjeff int (*resize_cq)(struct ibv_cq *cq, int cqe); 186219820Sjeff int (*destroy_cq)(struct ibv_cq *cq); 187219820Sjeff struct ibv_srq * (*create_srq)(struct ibv_pd *pd, 188219820Sjeff struct ibv_srq_init_attr *srq_init_attr); 189219820Sjeff int (*modify_srq)(struct ibv_srq *srq, 190219820Sjeff struct ibv_srq_attr *srq_attr, 191219820Sjeff int srq_attr_mask); 192219820Sjeff int (*query_srq)(struct ibv_srq *srq, 193219820Sjeff struct ibv_srq_attr *srq_attr); 194219820Sjeff int (*destroy_srq)(struct ibv_srq *srq); 195219820Sjeff int (*post_srq_recv)(struct ibv_srq_1_0 *srq, 196219820Sjeff struct ibv_recv_wr_1_0 *recv_wr, 197219820Sjeff struct ibv_recv_wr_1_0 **bad_recv_wr); 198219820Sjeff struct ibv_qp * (*create_qp)(struct ibv_pd *pd, struct ibv_qp_init_attr *attr); 199219820Sjeff int (*query_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, 200219820Sjeff int attr_mask, 201219820Sjeff struct ibv_qp_init_attr *init_attr); 202219820Sjeff int (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, 203219820Sjeff int attr_mask); 204219820Sjeff int (*destroy_qp)(struct ibv_qp *qp); 205219820Sjeff int (*post_send)(struct ibv_qp_1_0 *qp, 206219820Sjeff struct ibv_send_wr_1_0 *wr, 207219820Sjeff struct ibv_send_wr_1_0 **bad_wr); 208219820Sjeff int (*post_recv)(struct ibv_qp_1_0 *qp, 209219820Sjeff struct ibv_recv_wr_1_0 *wr, 210219820Sjeff struct ibv_recv_wr_1_0 **bad_wr); 211219820Sjeff struct ibv_ah * (*create_ah)(struct ibv_pd *pd, struct ibv_ah_attr *attr); 212219820Sjeff int (*destroy_ah)(struct ibv_ah *ah); 213219820Sjeff int (*attach_mcast)(struct ibv_qp *qp, union ibv_gid *gid, 214219820Sjeff uint16_t lid); 215219820Sjeff int (*detach_mcast)(struct ibv_qp *qp, union ibv_gid *gid, 216219820Sjeff uint16_t lid); 217219820Sjeff}; 218219820Sjeff 219219820Sjeffstruct ibv_context_1_0 { 220219820Sjeff struct ibv_device_1_0 *device; 221219820Sjeff struct ibv_context_ops_1_0 ops; 222219820Sjeff int cmd_fd; 223219820Sjeff int async_fd; 224219820Sjeff int num_comp_vectors; 225219820Sjeff 226219820Sjeff struct ibv_context *real_context; /* was abi_compat member */ 227219820Sjeff}; 228219820Sjeff 229219820Sjeffstruct ibv_device_1_0 **__ibv_get_device_list_1_0(int *num) 230219820Sjeff{ 231219820Sjeff struct ibv_device **real_list; 232219820Sjeff struct ibv_device_1_0 **l; 233219820Sjeff int i, n; 234219820Sjeff 235219820Sjeff real_list = ibv_get_device_list(&n); 236219820Sjeff if (!real_list) 237219820Sjeff return NULL; 238219820Sjeff 239219820Sjeff l = calloc(n + 2, sizeof (struct ibv_device_1_0 *)); 240219820Sjeff if (!l) 241219820Sjeff return NULL; 242219820Sjeff 243219820Sjeff l[0] = (void *) real_list; 244219820Sjeff 245219820Sjeff for (i = 0; i < n; ++i) { 246219820Sjeff l[i + 1] = calloc(1, sizeof (struct ibv_device_1_0)); 247219820Sjeff if (!l[i + 1]) 248219820Sjeff goto fail; 249219820Sjeff l[i + 1]->real_device = real_list[i]; 250219820Sjeff } 251219820Sjeff 252219820Sjeff if (num) 253219820Sjeff *num = n; 254219820Sjeff 255219820Sjeff return l + 1; 256219820Sjeff 257219820Sjefffail: 258219820Sjeff for (i = 1; i <= n; ++i) 259219820Sjeff if (l[i]) 260219820Sjeff free(l[i]); 261219820Sjeff ibv_free_device_list(real_list); 262219820Sjeff return NULL; 263219820Sjeff} 264219820Sjeffsymver(__ibv_get_device_list_1_0, ibv_get_device_list, IBVERBS_1.0); 265219820Sjeff 266219820Sjeffvoid __ibv_free_device_list_1_0(struct ibv_device_1_0 **list) 267219820Sjeff{ 268219820Sjeff struct ibv_device_1_0 **l = list; 269219820Sjeff 270219820Sjeff while (*l) { 271219820Sjeff free(*l); 272219820Sjeff ++l; 273219820Sjeff } 274219820Sjeff 275219820Sjeff ibv_free_device_list((void *) list[-1]); 276219820Sjeff free(list - 1); 277219820Sjeff} 278219820Sjeffsymver(__ibv_free_device_list_1_0, ibv_free_device_list, IBVERBS_1.0); 279219820Sjeff 280219820Sjeffconst char *__ibv_get_device_name_1_0(struct ibv_device_1_0 *device) 281219820Sjeff{ 282219820Sjeff return ibv_get_device_name(device->real_device); 283219820Sjeff} 284219820Sjeffsymver(__ibv_get_device_name_1_0, ibv_get_device_name, IBVERBS_1.0); 285219820Sjeff 286219820Sjeffuint64_t __ibv_get_device_guid_1_0(struct ibv_device_1_0 *device) 287219820Sjeff{ 288219820Sjeff return ibv_get_device_guid(device->real_device); 289219820Sjeff} 290219820Sjeffsymver(__ibv_get_device_guid_1_0, ibv_get_device_guid, IBVERBS_1.0); 291219820Sjeff 292219820Sjeffstatic int poll_cq_wrapper_1_0(struct ibv_cq_1_0 *cq, int num_entries, 293219820Sjeff struct ibv_wc *wc) 294219820Sjeff{ 295219820Sjeff return cq->context->real_context->ops.poll_cq(cq->real_cq, num_entries, wc); 296219820Sjeff} 297219820Sjeff 298219820Sjeffstatic int req_notify_cq_wrapper_1_0(struct ibv_cq_1_0 *cq, int sol_only) 299219820Sjeff{ 300219820Sjeff return cq->context->real_context->ops.req_notify_cq(cq->real_cq, sol_only); 301219820Sjeff} 302219820Sjeff 303219820Sjeffstatic int post_srq_recv_wrapper_1_0(struct ibv_srq_1_0 *srq, struct ibv_recv_wr_1_0 *wr, 304219820Sjeff struct ibv_recv_wr_1_0 **bad_wr) 305219820Sjeff{ 306219820Sjeff struct ibv_recv_wr_1_0 *w; 307219820Sjeff struct ibv_recv_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr; 308219820Sjeff int ret; 309219820Sjeff 310219820Sjeff for (w = wr; w; w = w->next) { 311219820Sjeff real_wr = alloca(sizeof *real_wr); 312219820Sjeff real_wr->wr_id = w->wr_id; 313219820Sjeff real_wr->sg_list = w->sg_list; 314219820Sjeff real_wr->num_sge = w->num_sge; 315219820Sjeff real_wr->next = NULL; 316219820Sjeff if (tail_wr) 317219820Sjeff tail_wr->next = real_wr; 318219820Sjeff else 319219820Sjeff head_wr = real_wr; 320219820Sjeff 321219820Sjeff tail_wr = real_wr; 322219820Sjeff } 323219820Sjeff 324219820Sjeff ret = srq->context->real_context->ops.post_srq_recv(srq->real_srq, head_wr, 325219820Sjeff &real_bad_wr); 326219820Sjeff 327219820Sjeff if (ret) { 328219820Sjeff for (real_wr = head_wr, w = wr; 329219820Sjeff real_wr; 330219820Sjeff real_wr = real_wr->next, w = w->next) 331219820Sjeff if (real_wr == real_bad_wr) { 332219820Sjeff *bad_wr = w; 333219820Sjeff break; 334219820Sjeff } 335219820Sjeff } 336219820Sjeff 337219820Sjeff return ret; 338219820Sjeff} 339219820Sjeff 340219820Sjeffstatic int post_send_wrapper_1_0(struct ibv_qp_1_0 *qp, struct ibv_send_wr_1_0 *wr, 341219820Sjeff struct ibv_send_wr_1_0 **bad_wr) 342219820Sjeff{ 343219820Sjeff struct ibv_send_wr_1_0 *w; 344219820Sjeff struct ibv_send_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr; 345219820Sjeff int is_ud = qp->qp_type == IBV_QPT_UD; 346219820Sjeff int ret; 347219820Sjeff 348219820Sjeff for (w = wr; w; w = w->next) { 349219820Sjeff real_wr = alloca(sizeof *real_wr); 350219820Sjeff real_wr->wr_id = w->wr_id; 351219820Sjeff real_wr->next = NULL; 352219820Sjeff 353219820Sjeff memcpy(&real_wr->sg_list, &w->sg_list, 354219820Sjeff sizeof *w - offsetof(struct ibv_send_wr, sg_list)); 355219820Sjeff 356219820Sjeff if (is_ud) 357219820Sjeff real_wr->wr.ud.ah = w->wr.ud.ah->real_ah; 358219820Sjeff 359219820Sjeff if (tail_wr) 360219820Sjeff tail_wr->next = real_wr; 361219820Sjeff else 362219820Sjeff head_wr = real_wr; 363219820Sjeff 364219820Sjeff tail_wr = real_wr; 365219820Sjeff } 366219820Sjeff 367219820Sjeff ret = qp->context->real_context->ops.post_send(qp->real_qp, head_wr, 368219820Sjeff &real_bad_wr); 369219820Sjeff 370219820Sjeff if (ret) { 371219820Sjeff for (real_wr = head_wr, w = wr; 372219820Sjeff real_wr; 373219820Sjeff real_wr = real_wr->next, w = w->next) 374219820Sjeff if (real_wr == real_bad_wr) { 375219820Sjeff *bad_wr = w; 376219820Sjeff break; 377219820Sjeff } 378219820Sjeff } 379219820Sjeff 380219820Sjeff return ret; 381219820Sjeff} 382219820Sjeff 383219820Sjeffstatic int post_recv_wrapper_1_0(struct ibv_qp_1_0 *qp, struct ibv_recv_wr_1_0 *wr, 384219820Sjeff struct ibv_recv_wr_1_0 **bad_wr) 385219820Sjeff{ 386219820Sjeff struct ibv_recv_wr_1_0 *w; 387219820Sjeff struct ibv_recv_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr; 388219820Sjeff int ret; 389219820Sjeff 390219820Sjeff for (w = wr; w; w = w->next) { 391219820Sjeff real_wr = alloca(sizeof *real_wr); 392219820Sjeff real_wr->wr_id = w->wr_id; 393219820Sjeff real_wr->sg_list = w->sg_list; 394219820Sjeff real_wr->num_sge = w->num_sge; 395219820Sjeff real_wr->next = NULL; 396219820Sjeff if (tail_wr) 397219820Sjeff tail_wr->next = real_wr; 398219820Sjeff else 399219820Sjeff head_wr = real_wr; 400219820Sjeff 401219820Sjeff tail_wr = real_wr; 402219820Sjeff } 403219820Sjeff 404219820Sjeff ret = qp->context->real_context->ops.post_recv(qp->real_qp, head_wr, 405219820Sjeff &real_bad_wr); 406219820Sjeff 407219820Sjeff if (ret) { 408219820Sjeff for (real_wr = head_wr, w = wr; 409219820Sjeff real_wr; 410219820Sjeff real_wr = real_wr->next, w = w->next) 411219820Sjeff if (real_wr == real_bad_wr) { 412219820Sjeff *bad_wr = w; 413219820Sjeff break; 414219820Sjeff } 415219820Sjeff } 416219820Sjeff 417219820Sjeff return ret; 418219820Sjeff} 419219820Sjeff 420219820Sjeffstruct ibv_context_1_0 *__ibv_open_device_1_0(struct ibv_device_1_0 *device) 421219820Sjeff{ 422219820Sjeff struct ibv_context *real_ctx; 423219820Sjeff struct ibv_context_1_0 *ctx; 424219820Sjeff 425219820Sjeff ctx = malloc(sizeof *ctx); 426219820Sjeff if (!ctx) 427219820Sjeff return NULL; 428219820Sjeff 429219820Sjeff real_ctx = ibv_open_device(device->real_device); 430219820Sjeff if (!real_ctx) { 431219820Sjeff free(ctx); 432219820Sjeff return NULL; 433219820Sjeff } 434219820Sjeff 435219820Sjeff ctx->device = device; 436219820Sjeff ctx->real_context = real_ctx; 437219820Sjeff 438219820Sjeff ctx->ops.poll_cq = poll_cq_wrapper_1_0; 439219820Sjeff ctx->ops.req_notify_cq = req_notify_cq_wrapper_1_0; 440219820Sjeff ctx->ops.post_send = post_send_wrapper_1_0; 441219820Sjeff ctx->ops.post_recv = post_recv_wrapper_1_0; 442219820Sjeff ctx->ops.post_srq_recv = post_srq_recv_wrapper_1_0; 443219820Sjeff 444219820Sjeff return ctx; 445219820Sjeff} 446219820Sjeffsymver(__ibv_open_device_1_0, ibv_open_device, IBVERBS_1.0); 447219820Sjeff 448219820Sjeffint __ibv_close_device_1_0(struct ibv_context_1_0 *context) 449219820Sjeff{ 450219820Sjeff int ret; 451219820Sjeff 452219820Sjeff ret = ibv_close_device(context->real_context); 453219820Sjeff if (ret) 454219820Sjeff return ret; 455219820Sjeff 456219820Sjeff free(context); 457219820Sjeff return 0; 458219820Sjeff} 459219820Sjeffsymver(__ibv_close_device_1_0, ibv_close_device, IBVERBS_1.0); 460219820Sjeff 461219820Sjeffint __ibv_get_async_event_1_0(struct ibv_context_1_0 *context, 462219820Sjeff struct ibv_async_event *event) 463219820Sjeff{ 464219820Sjeff int ret; 465219820Sjeff 466219820Sjeff ret = ibv_get_async_event(context->real_context, event); 467219820Sjeff if (ret) 468219820Sjeff return ret; 469219820Sjeff 470219820Sjeff switch (event->event_type) { 471219820Sjeff case IBV_EVENT_CQ_ERR: 472219820Sjeff event->element.cq = event->element.cq->cq_context; 473219820Sjeff break; 474219820Sjeff 475219820Sjeff case IBV_EVENT_QP_FATAL: 476219820Sjeff case IBV_EVENT_QP_REQ_ERR: 477219820Sjeff case IBV_EVENT_QP_ACCESS_ERR: 478219820Sjeff case IBV_EVENT_COMM_EST: 479219820Sjeff case IBV_EVENT_SQ_DRAINED: 480219820Sjeff case IBV_EVENT_PATH_MIG: 481219820Sjeff case IBV_EVENT_PATH_MIG_ERR: 482219820Sjeff case IBV_EVENT_QP_LAST_WQE_REACHED: 483219820Sjeff event->element.qp = event->element.qp->qp_context; 484219820Sjeff break; 485219820Sjeff 486219820Sjeff case IBV_EVENT_SRQ_ERR: 487219820Sjeff case IBV_EVENT_SRQ_LIMIT_REACHED: 488219820Sjeff event->element.srq = event->element.srq->srq_context; 489219820Sjeff break; 490219820Sjeff 491219820Sjeff default: 492219820Sjeff break; 493219820Sjeff } 494219820Sjeff 495219820Sjeff return ret; 496219820Sjeff} 497219820Sjeffsymver(__ibv_get_async_event_1_0, ibv_get_async_event, IBVERBS_1.0); 498219820Sjeff 499219820Sjeffvoid __ibv_ack_async_event_1_0(struct ibv_async_event *event) 500219820Sjeff{ 501219820Sjeff struct ibv_async_event real_event = *event; 502219820Sjeff 503219820Sjeff switch (event->event_type) { 504219820Sjeff case IBV_EVENT_CQ_ERR: 505219820Sjeff real_event.element.cq = 506219820Sjeff ((struct ibv_cq_1_0 *) event->element.cq)->real_cq; 507219820Sjeff break; 508219820Sjeff 509219820Sjeff case IBV_EVENT_QP_FATAL: 510219820Sjeff case IBV_EVENT_QP_REQ_ERR: 511219820Sjeff case IBV_EVENT_QP_ACCESS_ERR: 512219820Sjeff case IBV_EVENT_COMM_EST: 513219820Sjeff case IBV_EVENT_SQ_DRAINED: 514219820Sjeff case IBV_EVENT_PATH_MIG: 515219820Sjeff case IBV_EVENT_PATH_MIG_ERR: 516219820Sjeff case IBV_EVENT_QP_LAST_WQE_REACHED: 517219820Sjeff real_event.element.qp = 518219820Sjeff ((struct ibv_qp_1_0 *) event->element.qp)->real_qp; 519219820Sjeff break; 520219820Sjeff 521219820Sjeff case IBV_EVENT_SRQ_ERR: 522219820Sjeff case IBV_EVENT_SRQ_LIMIT_REACHED: 523219820Sjeff real_event.element.srq = 524219820Sjeff ((struct ibv_srq_1_0 *) event->element.srq)->real_srq; 525219820Sjeff break; 526219820Sjeff 527219820Sjeff default: 528219820Sjeff break; 529219820Sjeff } 530219820Sjeff 531219820Sjeff ibv_ack_async_event(&real_event); 532219820Sjeff} 533219820Sjeffsymver(__ibv_ack_async_event_1_0, ibv_ack_async_event, IBVERBS_1.0); 534219820Sjeff 535219820Sjeffint __ibv_query_device_1_0(struct ibv_context_1_0 *context, 536219820Sjeff struct ibv_device_attr *device_attr) 537219820Sjeff{ 538219820Sjeff return ibv_query_device(context->real_context, device_attr); 539219820Sjeff} 540219820Sjeffsymver(__ibv_query_device_1_0, ibv_query_device, IBVERBS_1.0); 541219820Sjeff 542219820Sjeffint __ibv_query_port_1_0(struct ibv_context_1_0 *context, uint8_t port_num, 543219820Sjeff struct ibv_port_attr *port_attr) 544219820Sjeff{ 545219820Sjeff return ibv_query_port(context->real_context, port_num, port_attr); 546219820Sjeff} 547219820Sjeffsymver(__ibv_query_port_1_0, ibv_query_port, IBVERBS_1.0); 548219820Sjeff 549219820Sjeffint __ibv_query_gid_1_0(struct ibv_context_1_0 *context, uint8_t port_num, 550219820Sjeff int index, union ibv_gid *gid) 551219820Sjeff{ 552219820Sjeff return ibv_query_gid(context->real_context, port_num, index, gid); 553219820Sjeff} 554219820Sjeffsymver(__ibv_query_gid_1_0, ibv_query_gid, IBVERBS_1.0); 555219820Sjeff 556219820Sjeffint __ibv_query_pkey_1_0(struct ibv_context_1_0 *context, uint8_t port_num, 557219820Sjeff int index, uint16_t *pkey) 558219820Sjeff{ 559219820Sjeff return ibv_query_pkey(context->real_context, port_num, index, pkey); 560219820Sjeff} 561219820Sjeffsymver(__ibv_query_pkey_1_0, ibv_query_pkey, IBVERBS_1.0); 562219820Sjeff 563219820Sjeffstruct ibv_pd_1_0 *__ibv_alloc_pd_1_0(struct ibv_context_1_0 *context) 564219820Sjeff{ 565219820Sjeff struct ibv_pd *real_pd; 566219820Sjeff struct ibv_pd_1_0 *pd; 567219820Sjeff 568219820Sjeff pd = malloc(sizeof *pd); 569219820Sjeff if (!pd) 570219820Sjeff return NULL; 571219820Sjeff 572219820Sjeff real_pd = ibv_alloc_pd(context->real_context); 573219820Sjeff if (!real_pd) { 574219820Sjeff free(pd); 575219820Sjeff return NULL; 576219820Sjeff } 577219820Sjeff 578219820Sjeff pd->context = context; 579219820Sjeff pd->real_pd = real_pd; 580219820Sjeff 581219820Sjeff return pd; 582219820Sjeff} 583219820Sjeffsymver(__ibv_alloc_pd_1_0, ibv_alloc_pd, IBVERBS_1.0); 584219820Sjeff 585219820Sjeffint __ibv_dealloc_pd_1_0(struct ibv_pd_1_0 *pd) 586219820Sjeff{ 587219820Sjeff int ret; 588219820Sjeff 589219820Sjeff ret = ibv_dealloc_pd(pd->real_pd); 590219820Sjeff if (ret) 591219820Sjeff return ret; 592219820Sjeff 593219820Sjeff free(pd); 594219820Sjeff return 0; 595219820Sjeff} 596219820Sjeffsymver(__ibv_dealloc_pd_1_0, ibv_dealloc_pd, IBVERBS_1.0); 597219820Sjeff 598219820Sjeffstruct ibv_mr_1_0 *__ibv_reg_mr_1_0(struct ibv_pd_1_0 *pd, void *addr, 599219820Sjeff size_t length, int access) 600219820Sjeff{ 601219820Sjeff struct ibv_mr *real_mr; 602219820Sjeff struct ibv_mr_1_0 *mr; 603219820Sjeff 604219820Sjeff mr = malloc(sizeof *mr); 605219820Sjeff if (!mr) 606219820Sjeff return NULL; 607219820Sjeff 608219820Sjeff real_mr = ibv_reg_mr(pd->real_pd, addr, length, access); 609219820Sjeff if (!real_mr) { 610219820Sjeff free(mr); 611219820Sjeff return NULL; 612219820Sjeff } 613219820Sjeff 614219820Sjeff mr->context = pd->context; 615219820Sjeff mr->pd = pd; 616219820Sjeff mr->lkey = real_mr->lkey; 617219820Sjeff mr->rkey = real_mr->rkey; 618219820Sjeff mr->real_mr = real_mr; 619219820Sjeff 620219820Sjeff return mr; 621219820Sjeff} 622219820Sjeffsymver(__ibv_reg_mr_1_0, ibv_reg_mr, IBVERBS_1.0); 623219820Sjeff 624219820Sjeffint __ibv_dereg_mr_1_0(struct ibv_mr_1_0 *mr) 625219820Sjeff{ 626219820Sjeff int ret; 627219820Sjeff 628219820Sjeff ret = ibv_dereg_mr(mr->real_mr); 629219820Sjeff if (ret) 630219820Sjeff return ret; 631219820Sjeff 632219820Sjeff free(mr); 633219820Sjeff return 0; 634219820Sjeff} 635219820Sjeffsymver(__ibv_dereg_mr_1_0, ibv_dereg_mr, IBVERBS_1.0); 636219820Sjeff 637219820Sjeffstruct ibv_cq_1_0 *__ibv_create_cq_1_0(struct ibv_context_1_0 *context, int cqe, 638219820Sjeff void *cq_context, 639219820Sjeff struct ibv_comp_channel *channel, 640219820Sjeff int comp_vector) 641219820Sjeff{ 642219820Sjeff struct ibv_cq *real_cq; 643219820Sjeff struct ibv_cq_1_0 *cq; 644219820Sjeff 645219820Sjeff cq = malloc(sizeof *cq); 646219820Sjeff if (!cq) 647219820Sjeff return NULL; 648219820Sjeff 649219820Sjeff real_cq = ibv_create_cq(context->real_context, cqe, cq_context, 650219820Sjeff channel, comp_vector); 651219820Sjeff if (!real_cq) { 652219820Sjeff free(cq); 653219820Sjeff return NULL; 654219820Sjeff } 655219820Sjeff 656219820Sjeff cq->context = context; 657219820Sjeff cq->cq_context = cq_context; 658219820Sjeff cq->cqe = cqe; 659219820Sjeff cq->real_cq = real_cq; 660219820Sjeff 661219820Sjeff real_cq->cq_context = cq; 662219820Sjeff 663219820Sjeff return cq; 664219820Sjeff} 665219820Sjeffsymver(__ibv_create_cq_1_0, ibv_create_cq, IBVERBS_1.0); 666219820Sjeff 667219820Sjeffint __ibv_resize_cq_1_0(struct ibv_cq_1_0 *cq, int cqe) 668219820Sjeff{ 669219820Sjeff return ibv_resize_cq(cq->real_cq, cqe); 670219820Sjeff} 671219820Sjeffsymver(__ibv_resize_cq_1_0, ibv_resize_cq, IBVERBS_1.0); 672219820Sjeff 673219820Sjeffint __ibv_destroy_cq_1_0(struct ibv_cq_1_0 *cq) 674219820Sjeff{ 675219820Sjeff int ret; 676219820Sjeff 677219820Sjeff ret = ibv_destroy_cq(cq->real_cq); 678219820Sjeff if (ret) 679219820Sjeff return ret; 680219820Sjeff 681219820Sjeff free(cq); 682219820Sjeff return 0; 683219820Sjeff} 684219820Sjeffsymver(__ibv_destroy_cq_1_0, ibv_destroy_cq, IBVERBS_1.0); 685219820Sjeff 686219820Sjeffint __ibv_get_cq_event_1_0(struct ibv_comp_channel *channel, 687219820Sjeff struct ibv_cq_1_0 **cq, void **cq_context) 688219820Sjeff{ 689219820Sjeff struct ibv_cq *real_cq; 690219820Sjeff void *cq_ptr; 691219820Sjeff int ret; 692219820Sjeff 693219820Sjeff ret = ibv_get_cq_event(channel, &real_cq, &cq_ptr); 694219820Sjeff if (ret) 695219820Sjeff return ret; 696219820Sjeff 697219820Sjeff *cq = cq_ptr; 698219820Sjeff *cq_context = (*cq)->cq_context; 699219820Sjeff 700219820Sjeff return 0; 701219820Sjeff} 702219820Sjeffsymver(__ibv_get_cq_event_1_0, ibv_get_cq_event, IBVERBS_1.0); 703219820Sjeff 704219820Sjeffvoid __ibv_ack_cq_events_1_0(struct ibv_cq_1_0 *cq, unsigned int nevents) 705219820Sjeff{ 706219820Sjeff ibv_ack_cq_events(cq->real_cq, nevents); 707219820Sjeff} 708219820Sjeffsymver(__ibv_ack_cq_events_1_0, ibv_ack_cq_events, IBVERBS_1.0); 709219820Sjeff 710219820Sjeffstruct ibv_srq_1_0 *__ibv_create_srq_1_0(struct ibv_pd_1_0 *pd, 711219820Sjeff struct ibv_srq_init_attr *srq_init_attr) 712219820Sjeff{ 713219820Sjeff struct ibv_srq *real_srq; 714219820Sjeff struct ibv_srq_1_0 *srq; 715219820Sjeff 716219820Sjeff srq = malloc(sizeof *srq); 717219820Sjeff if (!srq) 718219820Sjeff return NULL; 719219820Sjeff 720219820Sjeff real_srq = ibv_create_srq(pd->real_pd, srq_init_attr); 721219820Sjeff if (!real_srq) { 722219820Sjeff free(srq); 723219820Sjeff return NULL; 724219820Sjeff } 725219820Sjeff 726219820Sjeff srq->context = pd->context; 727219820Sjeff srq->srq_context = srq_init_attr->srq_context; 728219820Sjeff srq->pd = pd; 729219820Sjeff srq->real_srq = real_srq; 730219820Sjeff 731219820Sjeff real_srq->srq_context = srq; 732219820Sjeff 733219820Sjeff return srq; 734219820Sjeff} 735219820Sjeffsymver(__ibv_create_srq_1_0, ibv_create_srq, IBVERBS_1.0); 736219820Sjeff 737219820Sjeffint __ibv_modify_srq_1_0(struct ibv_srq_1_0 *srq, 738219820Sjeff struct ibv_srq_attr *srq_attr, 739219820Sjeff int srq_attr_mask) 740219820Sjeff{ 741219820Sjeff return ibv_modify_srq(srq->real_srq, srq_attr, srq_attr_mask); 742219820Sjeff} 743219820Sjeffsymver(__ibv_modify_srq_1_0, ibv_modify_srq, IBVERBS_1.0); 744219820Sjeff 745219820Sjeffint __ibv_query_srq_1_0(struct ibv_srq_1_0 *srq, struct ibv_srq_attr *srq_attr) 746219820Sjeff{ 747219820Sjeff return ibv_query_srq(srq->real_srq, srq_attr); 748219820Sjeff} 749219820Sjeffsymver(__ibv_query_srq_1_0, ibv_query_srq, IBVERBS_1.0); 750219820Sjeff 751219820Sjeffint __ibv_destroy_srq_1_0(struct ibv_srq_1_0 *srq) 752219820Sjeff{ 753219820Sjeff int ret; 754219820Sjeff 755219820Sjeff ret = ibv_destroy_srq(srq->real_srq); 756219820Sjeff if (ret) 757219820Sjeff return ret; 758219820Sjeff 759219820Sjeff free(srq); 760219820Sjeff return 0; 761219820Sjeff} 762219820Sjeffsymver(__ibv_destroy_srq_1_0, ibv_destroy_srq, IBVERBS_1.0); 763219820Sjeff 764219820Sjeffstruct ibv_qp_1_0 *__ibv_create_qp_1_0(struct ibv_pd_1_0 *pd, 765219820Sjeff struct ibv_qp_init_attr_1_0 *qp_init_attr) 766219820Sjeff{ 767219820Sjeff struct ibv_qp *real_qp; 768219820Sjeff struct ibv_qp_1_0 *qp; 769219820Sjeff struct ibv_qp_init_attr real_init_attr; 770219820Sjeff 771219820Sjeff qp = malloc(sizeof *qp); 772219820Sjeff if (!qp) 773219820Sjeff return NULL; 774219820Sjeff 775219820Sjeff real_init_attr.qp_context = qp_init_attr->qp_context; 776219820Sjeff real_init_attr.send_cq = qp_init_attr->send_cq->real_cq; 777219820Sjeff real_init_attr.recv_cq = qp_init_attr->recv_cq->real_cq; 778219820Sjeff real_init_attr.srq = qp_init_attr->srq ? 779219820Sjeff qp_init_attr->srq->real_srq : NULL; 780219820Sjeff real_init_attr.cap = qp_init_attr->cap; 781219820Sjeff real_init_attr.qp_type = qp_init_attr->qp_type; 782219820Sjeff real_init_attr.sq_sig_all = qp_init_attr->sq_sig_all; 783219820Sjeff 784219820Sjeff real_qp = ibv_create_qp(pd->real_pd, &real_init_attr); 785219820Sjeff if (!real_qp) { 786219820Sjeff free(qp); 787219820Sjeff return NULL; 788219820Sjeff } 789219820Sjeff 790219820Sjeff qp->context = pd->context; 791219820Sjeff qp->qp_context = qp_init_attr->qp_context; 792219820Sjeff qp->pd = pd; 793219820Sjeff qp->send_cq = qp_init_attr->send_cq; 794219820Sjeff qp->recv_cq = qp_init_attr->recv_cq; 795219820Sjeff qp->srq = qp_init_attr->srq; 796219820Sjeff qp->qp_type = qp_init_attr->qp_type; 797219820Sjeff qp->qp_num = real_qp->qp_num; 798219820Sjeff qp->real_qp = real_qp; 799219820Sjeff 800219820Sjeff qp_init_attr->cap = real_init_attr.cap; 801219820Sjeff 802219820Sjeff real_qp->qp_context = qp; 803219820Sjeff 804219820Sjeff return qp; 805219820Sjeff} 806219820Sjeffsymver(__ibv_create_qp_1_0, ibv_create_qp, IBVERBS_1.0); 807219820Sjeff 808219820Sjeffint __ibv_query_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr, 809219820Sjeff int attr_mask, 810219820Sjeff struct ibv_qp_init_attr_1_0 *init_attr) 811219820Sjeff{ 812219820Sjeff struct ibv_qp_init_attr real_init_attr; 813219820Sjeff int ret; 814219820Sjeff 815219820Sjeff ret = ibv_query_qp(qp->real_qp, attr, attr_mask, &real_init_attr); 816219820Sjeff if (ret) 817219820Sjeff return ret; 818219820Sjeff 819219820Sjeff init_attr->qp_context = qp->qp_context; 820219820Sjeff init_attr->send_cq = real_init_attr.send_cq->cq_context; 821219820Sjeff init_attr->recv_cq = real_init_attr.recv_cq->cq_context; 822219820Sjeff init_attr->srq = real_init_attr.srq->srq_context; 823219820Sjeff init_attr->qp_type = real_init_attr.qp_type; 824219820Sjeff init_attr->cap = real_init_attr.cap; 825219820Sjeff init_attr->sq_sig_all = real_init_attr.sq_sig_all; 826219820Sjeff 827219820Sjeff return 0; 828219820Sjeff} 829219820Sjeffsymver(__ibv_query_qp_1_0, ibv_query_qp, IBVERBS_1.0); 830219820Sjeff 831219820Sjeffint __ibv_modify_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr, 832219820Sjeff int attr_mask) 833219820Sjeff{ 834219820Sjeff return ibv_modify_qp(qp->real_qp, attr, attr_mask); 835219820Sjeff} 836219820Sjeffsymver(__ibv_modify_qp_1_0, ibv_modify_qp, IBVERBS_1.0); 837219820Sjeff 838219820Sjeffint __ibv_destroy_qp_1_0(struct ibv_qp_1_0 *qp) 839219820Sjeff{ 840219820Sjeff int ret; 841219820Sjeff 842219820Sjeff ret = ibv_destroy_qp(qp->real_qp); 843219820Sjeff if (ret) 844219820Sjeff return ret; 845219820Sjeff 846219820Sjeff free(qp); 847219820Sjeff return 0; 848219820Sjeff} 849219820Sjeffsymver(__ibv_destroy_qp_1_0, ibv_destroy_qp, IBVERBS_1.0); 850219820Sjeff 851219820Sjeffstruct ibv_ah_1_0 *__ibv_create_ah_1_0(struct ibv_pd_1_0 *pd, 852219820Sjeff struct ibv_ah_attr *attr) 853219820Sjeff{ 854219820Sjeff struct ibv_ah *real_ah; 855219820Sjeff struct ibv_ah_1_0 *ah; 856219820Sjeff 857219820Sjeff ah = malloc(sizeof *ah); 858219820Sjeff if (!ah) 859219820Sjeff return NULL; 860219820Sjeff 861219820Sjeff real_ah = ibv_create_ah(pd->real_pd, attr); 862219820Sjeff if (!real_ah) { 863219820Sjeff free(ah); 864219820Sjeff return NULL; 865219820Sjeff } 866219820Sjeff 867219820Sjeff ah->context = pd->context; 868219820Sjeff ah->pd = pd; 869219820Sjeff ah->real_ah = real_ah; 870219820Sjeff 871219820Sjeff return ah; 872219820Sjeff} 873219820Sjeffsymver(__ibv_create_ah_1_0, ibv_create_ah, IBVERBS_1.0); 874219820Sjeff 875219820Sjeffint __ibv_destroy_ah_1_0(struct ibv_ah_1_0 *ah) 876219820Sjeff{ 877219820Sjeff int ret; 878219820Sjeff 879219820Sjeff ret = ibv_destroy_ah(ah->real_ah); 880219820Sjeff if (ret) 881219820Sjeff return ret; 882219820Sjeff 883219820Sjeff free(ah); 884219820Sjeff return 0; 885219820Sjeff} 886219820Sjeffsymver(__ibv_destroy_ah_1_0, ibv_destroy_ah, IBVERBS_1.0); 887219820Sjeff 888219820Sjeffint __ibv_attach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid, uint16_t lid) 889219820Sjeff{ 890219820Sjeff return ibv_attach_mcast(qp->real_qp, gid, lid); 891219820Sjeff} 892219820Sjeffsymver(__ibv_attach_mcast_1_0, ibv_attach_mcast, IBVERBS_1.0); 893219820Sjeff 894219820Sjeffint __ibv_detach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid, uint16_t lid) 895219820Sjeff{ 896219820Sjeff return ibv_detach_mcast(qp->real_qp, gid, lid); 897219820Sjeff} 898219820Sjeffsymver(__ibv_detach_mcast_1_0, ibv_detach_mcast, IBVERBS_1.0); 899