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 45struct ibv_pd_1_0 { 46 struct ibv_context_1_0 *context; 47 uint32_t handle; 48 49 struct ibv_pd *real_pd; 50}; 51 52struct 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 62struct 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 75struct 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 85struct 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 112struct 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 119struct 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 138struct 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 152struct 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 160struct 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 167struct 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 219struct 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 229struct 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 257fail: 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} 264symver(__ibv_get_device_list_1_0, ibv_get_device_list, IBVERBS_1.0); 265 266void __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} 278symver(__ibv_free_device_list_1_0, ibv_free_device_list, IBVERBS_1.0); 279 280const char *__ibv_get_device_name_1_0(struct ibv_device_1_0 *device) 281{ 282 return ibv_get_device_name(device->real_device); 283} 284symver(__ibv_get_device_name_1_0, ibv_get_device_name, IBVERBS_1.0); 285 286uint64_t __ibv_get_device_guid_1_0(struct ibv_device_1_0 *device) 287{ 288 return ibv_get_device_guid(device->real_device); 289} 290symver(__ibv_get_device_guid_1_0, ibv_get_device_guid, IBVERBS_1.0); 291 292static 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 298static 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 303static 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 340static 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 383static 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 420struct 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} 446symver(__ibv_open_device_1_0, ibv_open_device, IBVERBS_1.0); 447 448int __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} 459symver(__ibv_close_device_1_0, ibv_close_device, IBVERBS_1.0); 460 461int __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} 497symver(__ibv_get_async_event_1_0, ibv_get_async_event, IBVERBS_1.0); 498 499void __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} 533symver(__ibv_ack_async_event_1_0, ibv_ack_async_event, IBVERBS_1.0); 534 535int __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} 540symver(__ibv_query_device_1_0, ibv_query_device, IBVERBS_1.0); 541 542int __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} 547symver(__ibv_query_port_1_0, ibv_query_port, IBVERBS_1.0); 548 549int __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} 554symver(__ibv_query_gid_1_0, ibv_query_gid, IBVERBS_1.0); 555 556int __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} 561symver(__ibv_query_pkey_1_0, ibv_query_pkey, IBVERBS_1.0); 562 563struct 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} 583symver(__ibv_alloc_pd_1_0, ibv_alloc_pd, IBVERBS_1.0); 584 585int __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} 596symver(__ibv_dealloc_pd_1_0, ibv_dealloc_pd, IBVERBS_1.0); 597 598struct 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} 622symver(__ibv_reg_mr_1_0, ibv_reg_mr, IBVERBS_1.0); 623 624int __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} 635symver(__ibv_dereg_mr_1_0, ibv_dereg_mr, IBVERBS_1.0); 636 637struct 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} 665symver(__ibv_create_cq_1_0, ibv_create_cq, IBVERBS_1.0); 666 667int __ibv_resize_cq_1_0(struct ibv_cq_1_0 *cq, int cqe) 668{ 669 return ibv_resize_cq(cq->real_cq, cqe); 670} 671symver(__ibv_resize_cq_1_0, ibv_resize_cq, IBVERBS_1.0); 672 673int __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} 684symver(__ibv_destroy_cq_1_0, ibv_destroy_cq, IBVERBS_1.0); 685 686int __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} 702symver(__ibv_get_cq_event_1_0, ibv_get_cq_event, IBVERBS_1.0); 703 704void __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} 708symver(__ibv_ack_cq_events_1_0, ibv_ack_cq_events, IBVERBS_1.0); 709 710struct 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} 735symver(__ibv_create_srq_1_0, ibv_create_srq, IBVERBS_1.0); 736 737int __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} 743symver(__ibv_modify_srq_1_0, ibv_modify_srq, IBVERBS_1.0); 744 745int __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} 749symver(__ibv_query_srq_1_0, ibv_query_srq, IBVERBS_1.0); 750 751int __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} 762symver(__ibv_destroy_srq_1_0, ibv_destroy_srq, IBVERBS_1.0); 763 764struct 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} 806symver(__ibv_create_qp_1_0, ibv_create_qp, IBVERBS_1.0); 807 808int __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} 829symver(__ibv_query_qp_1_0, ibv_query_qp, IBVERBS_1.0); 830 831int __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} 836symver(__ibv_modify_qp_1_0, ibv_modify_qp, IBVERBS_1.0); 837 838int __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} 849symver(__ibv_destroy_qp_1_0, ibv_destroy_qp, IBVERBS_1.0); 850 851struct 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} 873symver(__ibv_create_ah_1_0, ibv_create_ah, IBVERBS_1.0); 874 875int __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} 886symver(__ibv_destroy_ah_1_0, ibv_destroy_ah, IBVERBS_1.0); 887 888int __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} 892symver(__ibv_attach_mcast_1_0, ibv_attach_mcast, IBVERBS_1.0); 893 894int __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} 898symver(__ibv_detach_mcast_1_0, ibv_detach_mcast, IBVERBS_1.0); 899