diff options
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 77 | ||||
-rw-r--r-- | include/target/iscsi/iscsi_transport.h | 2 |
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 | /* | 3464 | int |
3465 | * FIXME: Add support for F_BIT and C_BIT when the length is longer than | 3465 | iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, |
3466 | * MaxRecvDataSegmentLength. | 3466 | struct iscsi_text_rsp *hdr) |
3467 | */ | ||
3468 | static 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 | } | ||
3493 | EXPORT_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 | */ | ||
3499 | static 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); |
64 | extern void iscsit_build_task_mgt_rsp(struct iscsi_cmd *, struct iscsi_conn *, | 64 | extern void iscsit_build_task_mgt_rsp(struct iscsi_cmd *, struct iscsi_conn *, |
65 | struct iscsi_tm_rsp *); | 65 | struct iscsi_tm_rsp *); |
66 | extern int iscsit_build_text_rsp(struct iscsi_cmd *, struct iscsi_conn *, | ||
67 | struct iscsi_text_rsp *); | ||
66 | extern void iscsit_build_reject(struct iscsi_cmd *, struct iscsi_conn *, | 68 | extern void iscsit_build_reject(struct iscsi_cmd *, struct iscsi_conn *, |
67 | struct iscsi_reject *); | 69 | struct iscsi_reject *); |
68 | extern int iscsit_build_logout_rsp(struct iscsi_cmd *, struct iscsi_conn *, | 70 | extern int iscsit_build_logout_rsp(struct iscsi_cmd *, struct iscsi_conn *, |