static inline void isert_link_send_pdu_wrs(struct isert_cmnd *from_pdu, struct isert_cmnd *to_pdu, int wr_cnt) { isert_link_send_wrs(&from_pdu->wr[wr_cnt - 1], &to_pdu->wr[0]); to_pdu->wr[0].send_wr.next = NULL; }
int isert_prepare_rdma(struct isert_cmnd *isert_pdu, struct isert_connection *isert_conn, enum isert_wr_op op) { struct isert_buf *isert_buf = &isert_pdu->rdma_buf; struct isert_device *isert_dev = isert_conn->isert_dev; struct ib_device *ib_dev = isert_dev->ib_dev; int err; int buff_offset; int sg_offset, sg_cnt; int wr_cnt, i; isert_buf_init_sg(isert_buf, isert_pdu->iscsi.sg, isert_pdu->iscsi.sg_cnt, isert_pdu->iscsi.bufflen); if (op == ISER_WR_RDMA_WRITE) isert_buf->dma_dir = DMA_TO_DEVICE; else isert_buf->dma_dir = DMA_FROM_DEVICE; if (unlikely(isert_buf->sg_cnt > isert_pdu->n_sge)) { wr_cnt = isert_alloc_for_rdma(isert_pdu, isert_buf->sg_cnt, isert_conn); if (unlikely(wr_cnt)) goto out; } err = ib_dma_map_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, isert_buf->dma_dir); if (unlikely(!err)) { pr_err("Failed to DMA map iser sg:%p len:%d\n", isert_buf->sg, isert_buf->sg_cnt); wr_cnt = -EFAULT; goto out; } buff_offset = 0; sg_cnt = 0; for (wr_cnt = 0, sg_offset = 0; sg_offset < isert_buf->sg_cnt; ++wr_cnt) { sg_cnt = min((int)isert_conn->max_sge, isert_buf->sg_cnt - sg_offset); err = isert_wr_init(&isert_pdu->wr[wr_cnt], op, isert_buf, isert_conn, isert_pdu, isert_pdu->sg_pool, sg_offset, sg_cnt, buff_offset); if (unlikely(err < 0)) { wr_cnt = err; goto out; } buff_offset = err; sg_offset += sg_cnt; } for (i = 1; i < wr_cnt; ++i) isert_link_send_wrs(&isert_pdu->wr[i - 1], &isert_pdu->wr[i]); out: TRACE_EXIT_RES(wr_cnt); return wr_cnt; }