aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/target/iscsi/iscsi_target.c77
-rw-r--r--include/target/iscsi/iscsi_transport.h2
2 files changed, 44 insertions, 35 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index ae312c5d8a45..1f79a168f1c1 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -3461,52 +3461,62 @@ eob:
3461 return payload_len; 3461 return payload_len;
3462} 3462}
3463 3463
3464/* 3464int
3465 * FIXME: Add support for F_BIT and C_BIT when the length is longer than 3465iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
3466 * MaxRecvDataSegmentLength. 3466 struct iscsi_text_rsp *hdr)
3467 */
3468static int iscsit_send_text_rsp(
3469 struct iscsi_cmd *cmd,
3470 struct iscsi_conn *conn)
3471{ 3467{
3472 struct iscsi_text_rsp *hdr; 3468 int text_length, padding;
3473 struct kvec *iov;
3474 u32 padding = 0, tx_size = 0;
3475 int text_length, iov_count = 0;
3476 3469
3477 text_length = iscsit_build_sendtargets_response(cmd); 3470 text_length = iscsit_build_sendtargets_response(cmd);
3478 if (text_length < 0) 3471 if (text_length < 0)
3479 return text_length; 3472 return text_length;
3480 3473
3474 hdr->opcode = ISCSI_OP_TEXT_RSP;
3475 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
3481 padding = ((-text_length) & 3); 3476 padding = ((-text_length) & 3);
3482 if (padding != 0) {
3483 memset(cmd->buf_ptr + text_length, 0, padding);
3484 pr_debug("Attaching %u additional bytes for"
3485 " padding.\n", padding);
3486 }
3487
3488 hdr = (struct iscsi_text_rsp *) cmd->pdu;
3489 memset(hdr, 0, ISCSI_HDR_LEN);
3490 hdr->opcode = ISCSI_OP_TEXT_RSP;
3491 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
3492 hton24(hdr->dlength, text_length); 3477 hton24(hdr->dlength, text_length);
3493 hdr->itt = cmd->init_task_tag; 3478 hdr->itt = cmd->init_task_tag;
3494 hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); 3479 hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
3495 cmd->stat_sn = conn->stat_sn++; 3480 cmd->stat_sn = conn->stat_sn++;
3496 hdr->statsn = cpu_to_be32(cmd->stat_sn); 3481 hdr->statsn = cpu_to_be32(cmd->stat_sn);
3497 3482
3498 iscsit_increment_maxcmdsn(cmd, conn->sess); 3483 iscsit_increment_maxcmdsn(cmd, conn->sess);
3499 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 3484 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
3500 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 3485 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
3501 3486
3502 iov = &cmd->iov_misc[0]; 3487 pr_debug("Built Text Response: ITT: 0x%08x, StatSN: 0x%08x,"
3488 " Length: %u, CID: %hu\n", cmd->init_task_tag, cmd->stat_sn,
3489 text_length, conn->cid);
3490
3491 return text_length + padding;
3492}
3493EXPORT_SYMBOL(iscsit_build_text_rsp);
3503 3494
3495/*
3496 * FIXME: Add support for F_BIT and C_BIT when the length is longer than
3497 * MaxRecvDataSegmentLength.
3498 */
3499static int iscsit_send_text_rsp(
3500 struct iscsi_cmd *cmd,
3501 struct iscsi_conn *conn)
3502{
3503 struct iscsi_text_rsp *hdr = (struct iscsi_text_rsp *)cmd->pdu;
3504 struct kvec *iov;
3505 u32 tx_size = 0;
3506 int text_length, iov_count = 0, rc;
3507
3508 rc = iscsit_build_text_rsp(cmd, conn, hdr);
3509 if (rc < 0)
3510 return rc;
3511
3512 text_length = rc;
3513 iov = &cmd->iov_misc[0];
3504 iov[iov_count].iov_base = cmd->pdu; 3514 iov[iov_count].iov_base = cmd->pdu;
3505 iov[iov_count++].iov_len = ISCSI_HDR_LEN; 3515 iov[iov_count++].iov_len = ISCSI_HDR_LEN;
3506 iov[iov_count].iov_base = cmd->buf_ptr; 3516 iov[iov_count].iov_base = cmd->buf_ptr;
3507 iov[iov_count++].iov_len = text_length + padding; 3517 iov[iov_count++].iov_len = text_length;
3508 3518
3509 tx_size += (ISCSI_HDR_LEN + text_length + padding); 3519 tx_size += (ISCSI_HDR_LEN + text_length);
3510 3520
3511 if (conn->conn_ops->HeaderDigest) { 3521 if (conn->conn_ops->HeaderDigest) {
3512 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 3522 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
@@ -3522,7 +3532,7 @@ static int iscsit_send_text_rsp(
3522 3532
3523 if (conn->conn_ops->DataDigest) { 3533 if (conn->conn_ops->DataDigest) {
3524 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, 3534 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
3525 cmd->buf_ptr, (text_length + padding), 3535 cmd->buf_ptr, text_length,
3526 0, NULL, (u8 *)&cmd->data_crc); 3536 0, NULL, (u8 *)&cmd->data_crc);
3527 3537
3528 iov[iov_count].iov_base = &cmd->data_crc; 3538 iov[iov_count].iov_base = &cmd->data_crc;
@@ -3530,16 +3540,13 @@ static int iscsit_send_text_rsp(
3530 tx_size += ISCSI_CRC_LEN; 3540 tx_size += ISCSI_CRC_LEN;
3531 3541
3532 pr_debug("Attaching DataDigest for %u bytes of text" 3542 pr_debug("Attaching DataDigest for %u bytes of text"
3533 " data, CRC 0x%08x\n", (text_length + padding), 3543 " data, CRC 0x%08x\n", text_length,
3534 cmd->data_crc); 3544 cmd->data_crc);
3535 } 3545 }
3536 3546
3537 cmd->iov_misc_count = iov_count; 3547 cmd->iov_misc_count = iov_count;
3538 cmd->tx_size = tx_size; 3548 cmd->tx_size = tx_size;
3539 3549
3540 pr_debug("Built Text Response: ITT: 0x%08x, StatSN: 0x%08x,"
3541 " Length: %u, CID: %hu\n", cmd->init_task_tag, cmd->stat_sn,
3542 text_length, conn->cid);
3543 return 0; 3550 return 0;
3544} 3551}
3545 3552
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h
index 90f3b60d30c4..ce991ba9e887 100644
--- a/include/target/iscsi/iscsi_transport.h
+++ b/include/target/iscsi/iscsi_transport.h
@@ -63,6 +63,8 @@ extern void iscsit_build_nopin_rsp(struct iscsi_cmd *, struct iscsi_conn *,
63 struct iscsi_nopin *, bool); 63 struct iscsi_nopin *, bool);
64extern void iscsit_build_task_mgt_rsp(struct iscsi_cmd *, struct iscsi_conn *, 64extern void iscsit_build_task_mgt_rsp(struct iscsi_cmd *, struct iscsi_conn *,
65 struct iscsi_tm_rsp *); 65 struct iscsi_tm_rsp *);
66extern int iscsit_build_text_rsp(struct iscsi_cmd *, struct iscsi_conn *,
67 struct iscsi_text_rsp *);
66extern void iscsit_build_reject(struct iscsi_cmd *, struct iscsi_conn *, 68extern void iscsit_build_reject(struct iscsi_cmd *, struct iscsi_conn *,
67 struct iscsi_reject *); 69 struct iscsi_reject *);
68extern int iscsit_build_logout_rsp(struct iscsi_cmd *, struct iscsi_conn *, 70extern int iscsit_build_logout_rsp(struct iscsi_cmd *, struct iscsi_conn *,