+error:
+ DEBUG(0, (ibw_lasterr));
+ return -1;
+}
+
+int ibw_send(struct ibw_conn *conn, void *buf, void *key, uint32_t len)
+{
+ struct ibw_ctx_priv *pctx = talloc_get_type(conn->ctx->internal, struct ibw_ctx_priv);
+ struct ibw_wr *p = talloc_get_type(key, struct ibw_wr);
+ int rc;
+
+ assert(len>=sizeof(uint32_t));
+ *((uint32_t *)buf) = htonl(len);
+
+ if (len > pctx->opts.recv_bufsize) {
+ struct ibw_conn_priv *pconn = talloc_get_type(conn->internal, struct ibw_conn_priv);
+ int rlen = len;
+ char *packet = (char *)buf;
+ uint32_t recv_bufsize = pctx->opts.recv_bufsize;
+
+ DEBUG(10, ("ibw_send#frag(cmid: %p, buf: %p, len: %u)\n",
+ pconn->cm_id, buf, len));
+
+ /* single threaded => no race here: */
+ assert(p->ref_cnt==0);
+ while(rlen > recv_bufsize) {
+ rc = ibw_send_packet(conn, packet, p, recv_bufsize);
+ if (rc)
+ return rc;
+ packet += recv_bufsize;
+ rlen -= recv_bufsize;
+ p->ref_cnt++; /* not good to have it in ibw_send_packet */
+ }
+ if (rlen) {
+ rc = ibw_send_packet(conn, packet, p, rlen);
+ p->ref_cnt++; /* not good to have it in ibw_send_packet */
+ }
+ p->ref_cnt--; /* for the same handling */
+ } else {
+ assert(p->ref_cnt==0);
+ assert(p->queued_ref_cnt==0);
+
+ rc = ibw_send_packet(conn, buf, p, len);
+ }
+ return rc;