1 Added support for XRC receive-only QPs.
2 (OFED 1.3 libibverbs commit 6e99cddf835d4715ea7ca3641944e6285f27f2df)
5 1. checkpatch.pl cleanups
6 2. Fixed u64 alignment problems in kern-abi.h
7 3. eliminated unneeded default_symvers
8 4. Added ibv_xrc_rcv_xxx lines to libibverbs.map IBVERBS_1.1
10 Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
12 include/infiniband/driver.h | 12 ++-
13 include/infiniband/kern-abi.h | 99 +++++++++++++++++++-
14 include/infiniband/verbs.h | 123 +++++++++++++++++++++++
15 src/cmd.c | 215 +++++++++++++++++++++++++++++++++++++++++
16 src/device.c | 52 +++++-----
17 src/libibverbs.map | 10 ++
18 src/verbs.c | 59 +++++++++++
19 7 files changed, 543 insertions(+), 27 deletions(-)
21 Index: libibverbs/include/infiniband/driver.h
22 ===================================================================
23 --- libibverbs.orig/include/infiniband/driver.h 2009-11-01 15:18:20.624171000 +0200
24 +++ libibverbs/include/infiniband/driver.h 2009-11-01 15:18:24.572283000 +0200
25 @@ -144,7 +144,17 @@ int ibv_cmd_open_xrc_domain(struct ibv_c
26 struct ibv_open_xrc_domain_resp *resp,
28 int ibv_cmd_close_xrc_domain(struct ibv_xrc_domain *d);
30 +int ibv_cmd_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
31 + uint32_t *xrc_rcv_qpn);
32 +int ibv_cmd_modify_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_rcv_qpn,
33 + struct ibv_qp_attr *attr, int attr_mask);
34 +int ibv_cmd_query_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_rcv_qpn,
35 + struct ibv_qp_attr *attr, int attr_mask,
36 + struct ibv_qp_init_attr *init_attr);
37 +int ibv_cmd_reg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
38 + uint32_t xrc_qp_num);
39 +int ibv_cmd_unreg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
40 + uint32_t xrc_qp_num);
43 * sysfs helper functions
44 Index: libibverbs/include/infiniband/kern-abi.h
45 ===================================================================
46 --- libibverbs.orig/include/infiniband/kern-abi.h 2009-11-01 15:18:20.629168000 +0200
47 +++ libibverbs/include/infiniband/kern-abi.h 2009-11-01 15:18:24.577283000 +0200
48 @@ -88,7 +88,12 @@ enum {
49 IB_USER_VERBS_CMD_POST_SRQ_RECV,
50 IB_USER_VERBS_CMD_CREATE_XRC_SRQ,
51 IB_USER_VERBS_CMD_OPEN_XRC_DOMAIN,
52 - IB_USER_VERBS_CMD_CLOSE_XRC_DOMAIN
53 + IB_USER_VERBS_CMD_CLOSE_XRC_DOMAIN,
54 + IB_USER_VERBS_CMD_CREATE_XRC_RCV_QP,
55 + IB_USER_VERBS_CMD_MODIFY_XRC_RCV_QP,
56 + IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP,
57 + IB_USER_VERBS_CMD_REG_XRC_RCV_QP,
58 + IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP,
62 @@ -570,6 +575,93 @@ struct ibv_destroy_qp_resp {
63 __u32 events_reported;
66 +struct ibv_create_xrc_rcv_qp {
72 + __u32 xrc_domain_handle;
77 + __u32 max_inline_data;
81 + __u64 driver_data[0];
84 +struct ibv_create_xrc_rcv_qp_resp {
89 +struct ibv_modify_xrc_rcv_qp {
93 + __u32 xrc_domain_handle;
95 + struct ibv_qp_dest dest;
96 + struct ibv_qp_dest alt_dest;
102 + __u32 qp_access_flags;
104 + __u16 alt_pkey_index;
108 + __u8 path_mig_state;
109 + __u8 en_sqd_async_notify;
110 + __u8 max_rd_atomic;
111 + __u8 max_dest_rd_atomic;
112 + __u8 min_rnr_timer;
120 + __u64 driver_data[0];
123 +struct ibv_query_xrc_rcv_qp {
128 + __u32 xrc_domain_handle;
132 + __u64 driver_data[0];
135 +struct ibv_reg_xrc_rcv_qp {
139 + __u32 xrc_domain_handle;
141 + __u64 driver_data[0];
144 +struct ibv_unreg_xrc_rcv_qp {
148 + __u32 xrc_domain_handle;
150 + __u64 driver_data[0];
153 struct ibv_kern_send_wr {
156 @@ -848,6 +940,11 @@ enum {
157 IB_USER_VERBS_CMD_CREATE_XRC_SRQ_V2 = -1,
158 IB_USER_VERBS_CMD_OPEN_XRC_DOMAIN_V2 = -1,
159 IB_USER_VERBS_CMD_CLOSE_XRC_DOMAIN_V2 = -1,
160 + IB_USER_VERBS_CMD_CREATE_XRC_RCV_QP_V2 = -1,
161 + IB_USER_VERBS_CMD_MODIFY_XRC_RCV_QP_V2 = -1,
162 + IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP_V2 = -1,
163 + IB_USER_VERBS_CMD_REG_XRC_RCV_QP_V2 = -1,
164 + IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP_V2 = -1,
167 struct ibv_destroy_cq_v1 {
168 Index: libibverbs/include/infiniband/verbs.h
169 ===================================================================
170 --- libibverbs.orig/include/infiniband/verbs.h 2009-11-01 15:18:20.635171000 +0200
171 +++ libibverbs/include/infiniband/verbs.h 2009-11-01 15:18:24.585280000 +0200
172 @@ -205,12 +205,17 @@ enum ibv_event_type {
173 IBV_EVENT_CLIENT_REREGISTER
176 +enum ibv_event_flags {
177 + IBV_XRC_QP_EVENT_FLAG = 0x80000000,
180 struct ibv_async_event {
186 + uint32_t xrc_qp_num;
188 enum ibv_event_type event_type;
190 @@ -648,6 +653,22 @@ struct ibv_more_ops {
191 struct ibv_xrc_domain * (*open_xrc_domain)(struct ibv_context *context,
193 int (*close_xrc_domain)(struct ibv_xrc_domain *d);
194 + int (*create_xrc_rcv_qp)(struct ibv_qp_init_attr *init_attr,
195 + uint32_t *xrc_qp_num);
196 + int (*modify_xrc_rcv_qp)(struct ibv_xrc_domain *xrc_domain,
197 + uint32_t xrc_qp_num,
198 + struct ibv_qp_attr *attr,
200 + int (*query_xrc_rcv_qp)(struct ibv_xrc_domain *xrc_domain,
201 + uint32_t xrc_qp_num,
202 + struct ibv_qp_attr *attr,
204 + struct ibv_qp_init_attr *init_attr);
205 + int (*reg_xrc_rcv_qp)(struct ibv_xrc_domain *xrc_domain,
206 + uint32_t xrc_qp_num);
207 + int (*unreg_xrc_rcv_qp)(struct ibv_xrc_domain *xrc_domain,
208 + uint32_t xrc_qp_num);
212 struct ibv_context_ops {
213 @@ -1174,6 +1195,108 @@ struct ibv_xrc_domain *ibv_open_xrc_doma
215 int ibv_close_xrc_domain(struct ibv_xrc_domain *d);
218 + * ibv_create_xrc_rcv_qp - creates an XRC QP for serving as a receive-side-only QP,
220 + * This QP is created in kernel space, and persists until the last process
221 + * registered for the QP calls ibv_unreg_xrc_rcv_qp() (at which time the QP
224 + * @init_attr: init attributes to use for QP. xrc domain MUST be included here.
225 + * All other fields are ignored.
227 + * @xrc_rcv_qpn: qp_num of created QP (if success). To be passed to the
228 + * remote node (sender). The remote node will use xrc_rcv_qpn
229 + * in ibv_post_send when sending to XRC SRQ's on this host
230 + * in the same xrc domain.
232 + * RETURNS: success (0), or a (negative) error value.
234 + * NOTE: this verb also registers the calling user-process with the QP at its
235 + * creation time (implicit call to ibv_reg_xrc_rcv_qp), to avoid race
236 + * conditions. The creating process will need to call ibv_unreg_xrc_qp()
237 + * for the QP to release it from this process.
239 +int ibv_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
240 + uint32_t *xrc_rcv_qpn);
243 + * ibv_modify_xrc_rcv_qp - modifies an xrc_rcv qp.
245 + * @xrc_domain: xrc domain the QP belongs to (for verification).
246 + * @xrc_qp_num: The (24 bit) number of the XRC QP.
247 + * @attr: modify-qp attributes. The following fields must be specified:
248 + * for RESET_2_INIT: qp_state, pkey_index , port, qp_access_flags
249 + * for INIT_2_RTR: qp_state, path_mtu, dest_qp_num, rq_psn,
250 + * max_dest_rd_atomic, min_rnr_timer, ah_attr
251 + * The QP need not be brought to RTS for the QP to operate as a
253 + * @attr_mask: bitmap indicating which attributes are provided in the attr
254 + * struct. Used for validity checking.
255 + * The following bits must be set:
256 + * for RESET_2_INIT: IBV_QP_PKEY_INDEX, IBV_QP_PORT,
257 + * IBV_QP_ACCESS_FLAGS, IBV_QP_STATE
258 + * for INIT_2_RTR: IBV_QP_AV, IBV_QP_PATH_MTU, IBV_QP_DEST_QPN,
259 + * IBV_QP_RQ_PSN, IBV_QP_MAX_DEST_RD_ATOMIC,
260 + * IBV_QP_MIN_RNR_TIMER, IBV_QP_STATE
262 + * RETURNS: success (0), or a (positive) error value.
265 +int ibv_modify_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
266 + uint32_t xrc_qp_num,
267 + struct ibv_qp_attr *attr, int attr_mask);
270 + * ibv_query_xrc_rcv_qp - queries an xrc_rcv qp.
272 + * @xrc_domain: xrc domain the QP belongs to (for verification).
273 + * @xrc_qp_num: The (24 bit) number of the XRC QP.
274 + * @attr: for returning qp attributes.
275 + * @attr_mask: bitmap indicating which attributes to return.
276 + * @init_attr: for returning the init attributes
278 + * RETURNS: success (0), or a (positive) error value.
281 +int ibv_query_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain, uint32_t xrc_qp_num,
282 + struct ibv_qp_attr *attr, int attr_mask,
283 + struct ibv_qp_init_attr *init_attr);
286 + * ibv_reg_xrc_rcv_qp: registers a user process with an XRC QP which serves as
287 + * a receive-side only QP.
289 + * @xrc_domain: xrc domain the QP belongs to (for verification).
290 + * @xrc_qp_num: The (24 bit) number of the XRC QP.
292 + * RETURNS: success (0),
293 + * or error (EINVAL), if:
294 + * 1. There is no such QP_num allocated.
295 + * 2. The QP is allocated, but is not an receive XRC QP
296 + * 3. The XRC QP does not belong to the given domain.
298 +int ibv_reg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain, uint32_t xrc_qp_num);
301 + * ibv_unreg_xrc_rcv_qp: detaches a user process from an XRC QP serving as
302 + * a receive-side only QP. If as a result, there are no remaining
303 + * userspace processes registered for this XRC QP, it is destroyed.
305 + * @xrc_domain: xrc domain the QP belongs to (for verification).
306 + * @xrc_qp_num: The (24 bit) number of the XRC QP.
308 + * RETURNS: success (0),
309 + * or error (EINVAL), if:
310 + * 1. There is no such QP_num allocated.
311 + * 2. The QP is allocated, but is not an XRC QP
312 + * 3. The XRC QP does not belong to the given domain.
313 + * NOTE: There is no reason to return a special code if the QP is destroyed.
314 + * The unregister simply succeeds.
316 +int ibv_unreg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
317 + uint32_t xrc_qp_num);
321 # undef __attribute_const
322 Index: libibverbs/src/cmd.c
323 ===================================================================
324 --- libibverbs.orig/src/cmd.c 2009-11-01 15:18:20.643167000 +0200
325 +++ libibverbs/src/cmd.c 2009-11-01 15:18:24.592284000 +0200
326 @@ -828,6 +828,188 @@ int ibv_cmd_modify_qp(struct ibv_qp *qp,
330 +int ibv_cmd_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
331 + uint32_t *xrc_rcv_qpn)
333 + struct ibv_create_xrc_rcv_qp cmd;
334 + struct ibv_create_xrc_rcv_qp_resp resp;
339 + IBV_INIT_CMD_RESP(&cmd, sizeof cmd, CREATE_XRC_RCV_QP, &resp,
342 + cmd.xrc_domain_handle = init_attr->xrc_domain->handle;
343 + cmd.max_send_wr = init_attr->cap.max_send_wr;
344 + cmd.max_recv_wr = init_attr->cap.max_recv_wr;
345 + cmd.max_send_sge = init_attr->cap.max_send_sge;
346 + cmd.max_recv_sge = init_attr->cap.max_recv_sge;
347 + cmd.max_inline_data = init_attr->cap.max_inline_data;
348 + cmd.sq_sig_all = init_attr->sq_sig_all;
349 + cmd.qp_type = init_attr->qp_type;
350 + cmd.reserved[0] = cmd.reserved[1] = 0;
352 + if (write(init_attr->xrc_domain->context->cmd_fd, &cmd, sizeof cmd) !=
356 + *xrc_rcv_qpn = resp.qpn;
361 +int ibv_cmd_modify_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num,
362 + struct ibv_qp_attr *attr, int attr_mask)
364 + struct ibv_modify_xrc_rcv_qp cmd;
369 + IBV_INIT_CMD(&cmd, sizeof cmd, MODIFY_XRC_RCV_QP);
371 + cmd.xrc_domain_handle = d->handle;
372 + cmd.qp_num = xrc_qp_num;
373 + cmd.attr_mask = attr_mask;
374 + cmd.qkey = attr->qkey;
375 + cmd.rq_psn = attr->rq_psn;
376 + cmd.sq_psn = attr->sq_psn;
377 + cmd.dest_qp_num = attr->dest_qp_num;
378 + cmd.qp_access_flags = attr->qp_access_flags;
379 + cmd.pkey_index = attr->pkey_index;
380 + cmd.alt_pkey_index = attr->alt_pkey_index;
381 + cmd.qp_state = attr->qp_state;
382 + cmd.cur_qp_state = attr->cur_qp_state;
383 + cmd.path_mtu = attr->path_mtu;
384 + cmd.path_mig_state = attr->path_mig_state;
385 + cmd.en_sqd_async_notify = attr->en_sqd_async_notify;
386 + cmd.max_rd_atomic = attr->max_rd_atomic;
387 + cmd.max_dest_rd_atomic = attr->max_dest_rd_atomic;
388 + cmd.min_rnr_timer = attr->min_rnr_timer;
389 + cmd.port_num = attr->port_num;
390 + cmd.timeout = attr->timeout;
391 + cmd.retry_cnt = attr->retry_cnt;
392 + cmd.rnr_retry = attr->rnr_retry;
393 + cmd.alt_port_num = attr->alt_port_num;
394 + cmd.alt_timeout = attr->alt_timeout;
396 + memcpy(cmd.dest.dgid, attr->ah_attr.grh.dgid.raw, 16);
397 + cmd.dest.flow_label = attr->ah_attr.grh.flow_label;
398 + cmd.dest.dlid = attr->ah_attr.dlid;
399 + cmd.dest.reserved = 0;
400 + cmd.dest.sgid_index = attr->ah_attr.grh.sgid_index;
401 + cmd.dest.hop_limit = attr->ah_attr.grh.hop_limit;
402 + cmd.dest.traffic_class = attr->ah_attr.grh.traffic_class;
403 + cmd.dest.sl = attr->ah_attr.sl;
404 + cmd.dest.src_path_bits = attr->ah_attr.src_path_bits;
405 + cmd.dest.static_rate = attr->ah_attr.static_rate;
406 + cmd.dest.is_global = attr->ah_attr.is_global;
407 + cmd.dest.port_num = attr->ah_attr.port_num;
409 + memcpy(cmd.alt_dest.dgid, attr->alt_ah_attr.grh.dgid.raw, 16);
410 + cmd.alt_dest.flow_label = attr->alt_ah_attr.grh.flow_label;
411 + cmd.alt_dest.dlid = attr->alt_ah_attr.dlid;
412 + cmd.alt_dest.reserved = 0;
413 + cmd.alt_dest.sgid_index = attr->alt_ah_attr.grh.sgid_index;
414 + cmd.alt_dest.hop_limit = attr->alt_ah_attr.grh.hop_limit;
415 + cmd.alt_dest.traffic_class = attr->alt_ah_attr.grh.traffic_class;
416 + cmd.alt_dest.sl = attr->alt_ah_attr.sl;
417 + cmd.alt_dest.src_path_bits = attr->alt_ah_attr.src_path_bits;
418 + cmd.alt_dest.static_rate = attr->alt_ah_attr.static_rate;
419 + cmd.alt_dest.is_global = attr->alt_ah_attr.is_global;
420 + cmd.alt_dest.port_num = attr->alt_ah_attr.port_num;
422 + cmd.reserved[0] = cmd.reserved[1] = 0;
424 + if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
430 +int ibv_cmd_query_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num,
431 + struct ibv_qp_attr *attr, int attr_mask,
432 + struct ibv_qp_init_attr *init_attr)
434 + struct ibv_query_xrc_rcv_qp cmd;
435 + struct ibv_query_qp_resp resp;
440 + IBV_INIT_CMD_RESP(&cmd, sizeof cmd, QUERY_XRC_RCV_QP, &resp,
442 + cmd.xrc_domain_handle = d->handle;
443 + cmd.qp_num = xrc_qp_num;
444 + cmd.attr_mask = attr_mask;
446 + if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
449 + VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
451 + attr->qkey = resp.qkey;
452 + attr->rq_psn = resp.rq_psn;
453 + attr->sq_psn = resp.sq_psn;
454 + attr->dest_qp_num = resp.dest_qp_num;
455 + attr->qp_access_flags = resp.qp_access_flags;
456 + attr->pkey_index = resp.pkey_index;
457 + attr->alt_pkey_index = resp.alt_pkey_index;
458 + attr->qp_state = resp.qp_state;
459 + attr->cur_qp_state = resp.cur_qp_state;
460 + attr->path_mtu = resp.path_mtu;
461 + attr->path_mig_state = resp.path_mig_state;
462 + attr->sq_draining = resp.sq_draining;
463 + attr->max_rd_atomic = resp.max_rd_atomic;
464 + attr->max_dest_rd_atomic = resp.max_dest_rd_atomic;
465 + attr->min_rnr_timer = resp.min_rnr_timer;
466 + attr->port_num = resp.port_num;
467 + attr->timeout = resp.timeout;
468 + attr->retry_cnt = resp.retry_cnt;
469 + attr->rnr_retry = resp.rnr_retry;
470 + attr->alt_port_num = resp.alt_port_num;
471 + attr->alt_timeout = resp.alt_timeout;
472 + attr->cap.max_send_wr = resp.max_send_wr;
473 + attr->cap.max_recv_wr = resp.max_recv_wr;
474 + attr->cap.max_send_sge = resp.max_send_sge;
475 + attr->cap.max_recv_sge = resp.max_recv_sge;
476 + attr->cap.max_inline_data = resp.max_inline_data;
478 + memcpy(attr->ah_attr.grh.dgid.raw, resp.dest.dgid, 16);
479 + attr->ah_attr.grh.flow_label = resp.dest.flow_label;
480 + attr->ah_attr.dlid = resp.dest.dlid;
481 + attr->ah_attr.grh.sgid_index = resp.dest.sgid_index;
482 + attr->ah_attr.grh.hop_limit = resp.dest.hop_limit;
483 + attr->ah_attr.grh.traffic_class = resp.dest.traffic_class;
484 + attr->ah_attr.sl = resp.dest.sl;
485 + attr->ah_attr.src_path_bits = resp.dest.src_path_bits;
486 + attr->ah_attr.static_rate = resp.dest.static_rate;
487 + attr->ah_attr.is_global = resp.dest.is_global;
488 + attr->ah_attr.port_num = resp.dest.port_num;
490 + memcpy(attr->alt_ah_attr.grh.dgid.raw, resp.alt_dest.dgid, 16);
491 + attr->alt_ah_attr.grh.flow_label = resp.alt_dest.flow_label;
492 + attr->alt_ah_attr.dlid = resp.alt_dest.dlid;
493 + attr->alt_ah_attr.grh.sgid_index = resp.alt_dest.sgid_index;
494 + attr->alt_ah_attr.grh.hop_limit = resp.alt_dest.hop_limit;
495 + attr->alt_ah_attr.grh.traffic_class = resp.alt_dest.traffic_class;
496 + attr->alt_ah_attr.sl = resp.alt_dest.sl;
497 + attr->alt_ah_attr.src_path_bits = resp.alt_dest.src_path_bits;
498 + attr->alt_ah_attr.static_rate = resp.alt_dest.static_rate;
499 + attr->alt_ah_attr.is_global = resp.alt_dest.is_global;
500 + attr->alt_ah_attr.port_num = resp.alt_dest.port_num;
502 + init_attr->cap.max_send_wr = resp.max_send_wr;
503 + init_attr->cap.max_recv_wr = resp.max_recv_wr;
504 + init_attr->cap.max_send_sge = resp.max_send_sge;
505 + init_attr->cap.max_recv_sge = resp.max_recv_sge;
506 + init_attr->cap.max_inline_data = resp.max_inline_data;
507 + init_attr->sq_sig_all = resp.sq_sig_all;
512 static int ibv_cmd_destroy_qp_v1(struct ibv_qp *qp)
514 struct ibv_destroy_qp_v1 cmd;
515 @@ -1192,3 +1374,36 @@ int ibv_cmd_close_xrc_domain(struct ibv_
519 +int ibv_cmd_reg_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num)
521 + struct ibv_reg_xrc_rcv_qp cmd;
526 + IBV_INIT_CMD(&cmd, sizeof cmd, REG_XRC_RCV_QP);
527 + cmd.xrc_domain_handle = d->handle;
528 + cmd.qp_num = xrc_qp_num;
530 + if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
535 +int ibv_cmd_unreg_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num)
537 + struct ibv_unreg_xrc_rcv_qp cmd;
542 + IBV_INIT_CMD(&cmd, sizeof cmd, UNREG_XRC_RCV_QP);
543 + cmd.xrc_domain_handle = d->handle;
544 + cmd.qp_num = xrc_qp_num;
546 + if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
552 Index: libibverbs/src/device.c
553 ===================================================================
554 --- libibverbs.orig/src/device.c 2009-11-01 15:18:17.794116000 +0200
555 +++ libibverbs/src/device.c 2009-11-01 15:18:24.597279000 +0200
556 @@ -191,31 +191,33 @@ int __ibv_get_async_event(struct ibv_con
558 event->event_type = ev.event_type;
560 - switch (event->event_type) {
561 - case IBV_EVENT_CQ_ERR:
562 - event->element.cq = (void *) (uintptr_t) ev.element;
565 - case IBV_EVENT_QP_FATAL:
566 - case IBV_EVENT_QP_REQ_ERR:
567 - case IBV_EVENT_QP_ACCESS_ERR:
568 - case IBV_EVENT_COMM_EST:
569 - case IBV_EVENT_SQ_DRAINED:
570 - case IBV_EVENT_PATH_MIG:
571 - case IBV_EVENT_PATH_MIG_ERR:
572 - case IBV_EVENT_QP_LAST_WQE_REACHED:
573 - event->element.qp = (void *) (uintptr_t) ev.element;
576 - case IBV_EVENT_SRQ_ERR:
577 - case IBV_EVENT_SRQ_LIMIT_REACHED:
578 - event->element.srq = (void *) (uintptr_t) ev.element;
582 - event->element.port_num = ev.element;
585 + if (event->event_type & IBV_XRC_QP_EVENT_FLAG) {
586 + event->element.xrc_qp_num = ev.element;
588 + switch (event->event_type) {
589 + case IBV_EVENT_CQ_ERR:
590 + event->element.cq = (void *) (uintptr_t) ev.element;
593 + case IBV_EVENT_QP_FATAL:
594 + case IBV_EVENT_QP_REQ_ERR:
595 + case IBV_EVENT_QP_ACCESS_ERR:
596 + case IBV_EVENT_COMM_EST:
597 + case IBV_EVENT_SQ_DRAINED:
598 + case IBV_EVENT_PATH_MIG:
599 + case IBV_EVENT_PATH_MIG_ERR:
600 + case IBV_EVENT_QP_LAST_WQE_REACHED:
601 + event->element.qp = (void *) (uintptr_t) ev.element;
604 + case IBV_EVENT_SRQ_ERR:
605 + case IBV_EVENT_SRQ_LIMIT_REACHED:
606 + event->element.srq = (void *) (uintptr_t) ev.element;
609 + event->element.port_num = ev.element;
613 if (context->ops.async_event)
614 context->ops.async_event(event);
615 Index: libibverbs/src/libibverbs.map
616 ===================================================================
617 --- libibverbs.orig/src/libibverbs.map 2009-11-01 15:18:20.646169000 +0200
618 +++ libibverbs/src/libibverbs.map 2009-11-01 15:18:24.600279000 +0200
619 @@ -97,6 +97,16 @@ IBVERBS_1.1 {
620 ibv_cmd_open_xrc_domain;
621 ibv_close_xrc_domain;
622 ibv_cmd_close_xrc_domain;
623 + ibv_create_xrc_rcv_qp;
624 + ibv_cmd_create_xrc_rcv_qp;
625 + ibv_modify_xrc_rcv_qp;
626 + ibv_cmd_modify_xrc_rcv_qp;
627 + ibv_query_xrc_rcv_qp;
628 + ibv_cmd_query_xrc_rcv_qp;
629 + ibv_reg_xrc_rcv_qp;
630 + ibv_cmd_reg_xrc_rcv_qp;
631 + ibv_unreg_xrc_rcv_qp;
632 + ibv_cmd_unreg_xrc_rcv_qp;
636 Index: libibverbs/src/verbs.c
637 ===================================================================
638 --- libibverbs.orig/src/verbs.c 2009-11-01 15:18:20.650169000 +0200
639 +++ libibverbs/src/verbs.c 2009-11-01 15:18:24.604279000 +0200
640 @@ -597,3 +597,62 @@ int ibv_close_xrc_domain(struct ibv_xrc_
642 return d->context->more_ops->close_xrc_domain(d);
645 +int ibv_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
646 + uint32_t *xrc_rcv_qpn)
648 + struct ibv_context *c;
649 + if (!init_attr || !(init_attr->xrc_domain))
652 + c = init_attr->xrc_domain->context;
656 + return c->more_ops->create_xrc_rcv_qp(init_attr,
660 +int ibv_modify_xrc_rcv_qp(struct ibv_xrc_domain *d,
661 + uint32_t xrc_rcv_qpn,
662 + struct ibv_qp_attr *attr,
668 + if (!d->context->more_ops)
671 + return d->context->more_ops->modify_xrc_rcv_qp(d, xrc_rcv_qpn, attr,
675 +int ibv_query_xrc_rcv_qp(struct ibv_xrc_domain *d,
676 + uint32_t xrc_rcv_qpn,
677 + struct ibv_qp_attr *attr,
679 + struct ibv_qp_init_attr *init_attr)
684 + if (!d->context->more_ops)
687 + return d->context->more_ops->query_xrc_rcv_qp(d, xrc_rcv_qpn, attr,
688 + attr_mask, init_attr);
691 +int ibv_reg_xrc_rcv_qp(struct ibv_xrc_domain *d,
692 + uint32_t xrc_rcv_qpn)
694 + return d->context->more_ops->reg_xrc_rcv_qp(d, xrc_rcv_qpn);
697 +int ibv_unreg_xrc_rcv_qp(struct ibv_xrc_domain *d,
698 + uint32_t xrc_rcv_qpn)
700 + return d->context->more_ops->unreg_xrc_rcv_qp(d, xrc_rcv_qpn);