/** * iser_send_command - send command PDU */ int iser_send_command(struct iscsi_conn *conn, struct iscsi_task *task) { struct iscsi_iser_conn *iser_conn = conn->dd_data; struct iscsi_iser_task *iser_task = task->dd_data; unsigned long edtl; int err; struct iser_data_buf *data_buf; struct iscsi_cmd *hdr = (struct iscsi_cmd *)task->hdr; struct scsi_cmnd *sc = task->sc; struct iser_tx_desc *tx_desc = &iser_task->desc; edtl = ntohl(hdr->data_length); /* build the tx desc regd header and add it to the tx desc dto */ tx_desc->type = ISCSI_TX_SCSI_COMMAND; iser_create_send_desc(iser_conn->ib_conn, tx_desc); if (hdr->flags & ISCSI_FLAG_CMD_READ) data_buf = &iser_task->data[ISER_DIR_IN]; else data_buf = &iser_task->data[ISER_DIR_OUT]; if (scsi_sg_count(sc)) { /* using a scatter list */ data_buf->buf = scsi_sglist(sc); data_buf->size = scsi_sg_count(sc); } data_buf->data_len = scsi_bufflen(sc); if (hdr->flags & ISCSI_FLAG_CMD_READ) { err = iser_prepare_read_cmd(task, edtl); if (err) goto send_command_error; } if (hdr->flags & ISCSI_FLAG_CMD_WRITE) { err = iser_prepare_write_cmd(task, task->imm_count, task->imm_count + task->unsol_r2t.data_length, edtl); if (err) goto send_command_error; } iser_task->status = ISER_TASK_STATUS_STARTED; err = iser_post_send(iser_conn->ib_conn, tx_desc); if (!err) return 0; send_command_error: iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err); return err; }
/** * iser_send_command - send command PDU */ int iser_send_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_iser_conn *iser_conn = conn->dd_data; struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; struct iser_dto *send_dto = NULL; unsigned long edtl; int err = 0; struct iser_data_buf *data_buf; struct iscsi_cmd *hdr = ctask->hdr; struct scsi_cmnd *sc = ctask->sc; if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); return -EPERM; } if (iser_check_xmit(conn, ctask)) return -ENOBUFS; edtl = ntohl(hdr->data_length); /* build the tx desc regd header and add it to the tx desc dto */ iser_ctask->desc.type = ISCSI_TX_SCSI_COMMAND; send_dto = &iser_ctask->desc.dto; send_dto->ctask = iser_ctask; iser_create_send_desc(iser_conn, &iser_ctask->desc); if (hdr->flags & ISCSI_FLAG_CMD_READ) data_buf = &iser_ctask->data[ISER_DIR_IN]; else data_buf = &iser_ctask->data[ISER_DIR_OUT]; if (sc->use_sg) { /* using a scatter list */ data_buf->buf = sc->request_buffer; data_buf->size = sc->use_sg; } else if (sc->request_bufflen) { /* using a single buffer - convert it into one entry SG */ sg_init_one(&data_buf->sg_single, sc->request_buffer, sc->request_bufflen); data_buf->buf = &data_buf->sg_single; data_buf->size = 1; } data_buf->data_len = sc->request_bufflen; if (hdr->flags & ISCSI_FLAG_CMD_READ) { err = iser_prepare_read_cmd(ctask, edtl); if (err) goto send_command_error; } if (hdr->flags & ISCSI_FLAG_CMD_WRITE) { err = iser_prepare_write_cmd(ctask, ctask->imm_count, ctask->imm_count + ctask->unsol_count, edtl); if (err) goto send_command_error; } iser_reg_single(iser_conn->ib_conn->device, send_dto->regd[0], DMA_TO_DEVICE); if (iser_post_receive_control(conn) != 0) { iser_err("post_recv failed!\n"); err = -ENOMEM; goto send_command_error; } iser_ctask->status = ISER_TASK_STATUS_STARTED; err = iser_post_send(&iser_ctask->desc); if (!err) return 0; send_command_error: iser_dto_buffs_release(send_dto); iser_err("conn %p failed ctask->itt %d err %d\n",conn, ctask->itt, err); return err; }