/** * iscsi_iser_task_init - Initialize task * @task: iscsi task * * Initialize the task for the scsi command or mgmt command. */ static int iscsi_iser_task_init(struct iscsi_task *task) { struct iscsi_iser_task *iser_task = task->dd_data; if (iser_initialize_task_headers(task, &iser_task->desc)) return -ENOMEM; /* mgmt task */ if (!task->sc) return 0; iser_task->command_sent = 0; iser_task_rdma_init(iser_task); return 0; }
/** * iscsi_iser_task_init() - Initialize iscsi-iser task * @task: iscsi task * * Initialize the task for the scsi command or mgmt command. * * Return: Returns zero on success or -ENOMEM when failing * to init task headers (dma mapping error). */ static int iscsi_iser_task_init(struct iscsi_task *task) { struct iscsi_iser_task *iser_task = task->dd_data; int ret; ret = iser_initialize_task_headers(task, &iser_task->desc); if (ret) { iser_err("Failed to init task %p, err = %d\n", iser_task, ret); return ret; } /* mgmt task */ if (!task->sc) return 0; iser_task->command_sent = 0; iser_task_rdma_init(iser_task); iser_task->sc = task->sc; return 0; }
/** * iser_send_data_out - send data out PDU */ int iser_send_data_out(struct iscsi_conn *conn, struct iscsi_task *task, struct iscsi_data *hdr) { struct iser_conn *iser_conn = conn->dd_data; struct iscsi_iser_task *iser_task = task->dd_data; struct iser_tx_desc *tx_desc = NULL; struct iser_mem_reg *mem_reg; unsigned long buf_offset; unsigned long data_seg_len; uint32_t itt; int err; struct ib_sge *tx_dsg; itt = (__force uint32_t)hdr->itt; data_seg_len = ntoh24(hdr->dlength); buf_offset = ntohl(hdr->offset); iser_dbg("%s itt %d dseg_len %d offset %d\n", __func__,(int)itt,(int)data_seg_len,(int)buf_offset); tx_desc = kmem_cache_zalloc(ig.desc_cache, GFP_ATOMIC); if (tx_desc == NULL) { iser_err("Failed to alloc desc for post dataout\n"); return -ENOMEM; } tx_desc->type = ISCSI_TX_DATAOUT; tx_desc->iser_header.flags = ISER_VER; memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr)); /* build the tx desc */ err = iser_initialize_task_headers(task, tx_desc); if (err) goto send_data_out_error; mem_reg = &iser_task->rdma_reg[ISER_DIR_OUT]; tx_dsg = &tx_desc->tx_sg[1]; tx_dsg->addr = mem_reg->sge.addr + buf_offset; tx_dsg->length = data_seg_len; tx_dsg->lkey = mem_reg->sge.lkey; tx_desc->num_sge = 2; if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) { iser_err("Offset:%ld & DSL:%ld in Data-Out " "inconsistent with total len:%ld, itt:%d\n", buf_offset, data_seg_len, iser_task->data[ISER_DIR_OUT].data_len, itt); err = -EINVAL; goto send_data_out_error; } iser_dbg("data-out itt: %d, offset: %ld, sz: %ld\n", itt, buf_offset, data_seg_len); err = iser_post_send(&iser_conn->ib_conn, tx_desc, true); if (!err) return 0; send_data_out_error: kmem_cache_free(ig.desc_cache, tx_desc); iser_err("conn %p failed err %d\n", conn, err); return err; }