diff options
author | Christoph Hellwig <hch@lst.de> | 2012-11-06 15:24:09 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-11-06 23:55:46 -0500 |
commit | de103c93aff0bed0ae984274e5dc8b95899badab (patch) | |
tree | 7db9bba755fa95772052e8d31285a38ba48f1a84 | |
parent | fecae40abb1ae9218bdbaa8b8e30bfb5ae43f522 (diff) |
target: pass sense_reason as a return value
Pass the sense reason as an explicit return value from the I/O submission
path instead of storing it in struct se_cmd and using negative return
values. This cleans up a lot of the code pathes, and with the sparse
annotations for the new sense_reason_t type allows for much better
error checking.
(nab: Convert spc_emulate_modesense + spc_emulate_modeselect to use
sense_reason_t with Roland's MODE SELECT changes)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Cc: Roland Dreier <roland@purestorage.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
24 files changed, 841 insertions, 1059 deletions
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index cf23c46185b2..e6fafc62acae 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -1730,7 +1730,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, | |||
1730 | uint64_t unpacked_lun; | 1730 | uint64_t unpacked_lun; |
1731 | u64 data_len; | 1731 | u64 data_len; |
1732 | enum dma_data_direction dir; | 1732 | enum dma_data_direction dir; |
1733 | int ret; | 1733 | sense_reason_t ret; |
1734 | 1734 | ||
1735 | BUG_ON(!send_ioctx); | 1735 | BUG_ON(!send_ioctx); |
1736 | 1736 | ||
@@ -1755,12 +1755,10 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, | |||
1755 | break; | 1755 | break; |
1756 | } | 1756 | } |
1757 | 1757 | ||
1758 | ret = srpt_get_desc_tbl(send_ioctx, srp_cmd, &dir, &data_len); | 1758 | if (srpt_get_desc_tbl(send_ioctx, srp_cmd, &dir, &data_len)) { |
1759 | if (ret) { | ||
1760 | printk(KERN_ERR "0x%llx: parsing SRP descriptor table failed.\n", | 1759 | printk(KERN_ERR "0x%llx: parsing SRP descriptor table failed.\n", |
1761 | srp_cmd->tag); | 1760 | srp_cmd->tag); |
1762 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 1761 | ret = TCM_INVALID_CDB_FIELD; |
1763 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1764 | kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); | 1762 | kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); |
1765 | goto send_sense; | 1763 | goto send_sense; |
1766 | } | 1764 | } |
@@ -1769,26 +1767,26 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, | |||
1769 | cmd->data_direction = dir; | 1767 | cmd->data_direction = dir; |
1770 | unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun, | 1768 | unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun, |
1771 | sizeof(srp_cmd->lun)); | 1769 | sizeof(srp_cmd->lun)); |
1772 | if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0) { | 1770 | ret = transport_lookup_cmd_lun(cmd, unpacked_lun); |
1771 | if (ret) { | ||
1773 | kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); | 1772 | kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); |
1774 | goto send_sense; | 1773 | goto send_sense; |
1775 | } | 1774 | } |
1776 | ret = target_setup_cmd_from_cdb(cmd, srp_cmd->cdb); | 1775 | ret = target_setup_cmd_from_cdb(cmd, srp_cmd->cdb); |
1777 | if (ret < 0) { | 1776 | if (ret) { |
1778 | kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); | 1777 | kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); |
1779 | if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) { | 1778 | if (ret == TCM_RESERVATION_CONFLICT) { |
1780 | srpt_queue_status(cmd); | 1779 | srpt_queue_status(cmd); |
1781 | return 0; | 1780 | return 0; |
1782 | } else | 1781 | } |
1783 | goto send_sense; | 1782 | goto send_sense; |
1784 | } | 1783 | } |
1785 | 1784 | ||
1786 | transport_handle_cdb_direct(cmd); | 1785 | transport_handle_cdb_direct(cmd); |
1787 | return 0; | 1786 | return 0; |
1788 | 1787 | ||
1789 | send_sense: | 1788 | send_sense: |
1790 | transport_send_check_condition_and_sense(cmd, cmd->scsi_sense_reason, | 1789 | transport_send_check_condition_and_sense(cmd, ret, 0); |
1791 | 0); | ||
1792 | return -1; | 1790 | return -1; |
1793 | } | 1791 | } |
1794 | 1792 | ||
@@ -1882,16 +1880,14 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch, | |||
1882 | send_ioctx->tag = srp_tsk->tag; | 1880 | send_ioctx->tag = srp_tsk->tag; |
1883 | tcm_tmr = srp_tmr_to_tcm(srp_tsk->tsk_mgmt_func); | 1881 | tcm_tmr = srp_tmr_to_tcm(srp_tsk->tsk_mgmt_func); |
1884 | if (tcm_tmr < 0) { | 1882 | if (tcm_tmr < 0) { |
1885 | send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1886 | send_ioctx->cmd.se_tmr_req->response = | 1883 | send_ioctx->cmd.se_tmr_req->response = |
1887 | TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED; | 1884 | TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED; |
1888 | goto process_tmr; | 1885 | goto fail; |
1889 | } | 1886 | } |
1890 | res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL); | 1887 | res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL); |
1891 | if (res < 0) { | 1888 | if (res < 0) { |
1892 | send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1893 | send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED; | 1889 | send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED; |
1894 | goto process_tmr; | 1890 | goto fail; |
1895 | } | 1891 | } |
1896 | 1892 | ||
1897 | unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_tsk->lun, | 1893 | unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_tsk->lun, |
@@ -1899,22 +1895,19 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch, | |||
1899 | res = transport_lookup_tmr_lun(&send_ioctx->cmd, unpacked_lun); | 1895 | res = transport_lookup_tmr_lun(&send_ioctx->cmd, unpacked_lun); |
1900 | if (res) { | 1896 | if (res) { |
1901 | pr_debug("rejecting TMR for LUN %lld\n", unpacked_lun); | 1897 | pr_debug("rejecting TMR for LUN %lld\n", unpacked_lun); |
1902 | send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1903 | send_ioctx->cmd.se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; | 1898 | send_ioctx->cmd.se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; |
1904 | goto process_tmr; | 1899 | goto fail; |
1905 | } | 1900 | } |
1906 | 1901 | ||
1907 | if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK) | 1902 | if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK) |
1908 | srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag); | 1903 | srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag); |
1909 | 1904 | ||
1910 | process_tmr: | ||
1911 | kref_get(&send_ioctx->kref); | 1905 | kref_get(&send_ioctx->kref); |
1912 | if (!(send_ioctx->cmd.se_cmd_flags & SCF_SCSI_CDB_EXCEPTION)) | 1906 | transport_generic_handle_tmr(&send_ioctx->cmd); |
1913 | transport_generic_handle_tmr(&send_ioctx->cmd); | 1907 | return; |
1914 | else | 1908 | fail: |
1915 | transport_send_check_condition_and_sense(cmd, | 1909 | kref_get(&send_ioctx->kref); |
1916 | cmd->scsi_sense_reason, 0); | 1910 | transport_send_check_condition_and_sense(cmd, 0, 0); // XXX: |
1917 | |||
1918 | } | 1911 | } |
1919 | 1912 | ||
1920 | /** | 1913 | /** |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 3d74f2f39ae1..c5696240d8f6 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -620,8 +620,8 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work) | |||
620 | return; | 620 | return; |
621 | } | 621 | } |
622 | 622 | ||
623 | cmd->se_cmd.scsi_sense_reason = TCM_CHECK_CONDITION_ABORT_CMD; | 623 | transport_generic_request_failure(&cmd->se_cmd, |
624 | transport_generic_request_failure(&cmd->se_cmd); | 624 | TCM_CHECK_CONDITION_ABORT_CMD); |
625 | return; | 625 | return; |
626 | } | 626 | } |
627 | 627 | ||
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 035c2c762537..093fb6010272 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -767,9 +767,8 @@ static int iscsit_handle_scsi_cmd( | |||
767 | struct iscsi_conn *conn, | 767 | struct iscsi_conn *conn, |
768 | unsigned char *buf) | 768 | unsigned char *buf) |
769 | { | 769 | { |
770 | int data_direction, cmdsn_ret = 0, immed_ret, ret, transport_ret; | 770 | int data_direction, payload_length, cmdsn_ret = 0, immed_ret; |
771 | int dump_immediate_data = 0, send_check_condition = 0, payload_length; | 771 | struct iscsi_cmd *cmd = NULL; |
772 | struct iscsi_cmd *cmd = NULL; | ||
773 | struct iscsi_scsi_req *hdr; | 772 | struct iscsi_scsi_req *hdr; |
774 | int iscsi_task_attr; | 773 | int iscsi_task_attr; |
775 | int sam_task_attr; | 774 | int sam_task_attr; |
@@ -956,38 +955,26 @@ done: | |||
956 | " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, | 955 | " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, |
957 | hdr->cmdsn, hdr->data_length, payload_length, conn->cid); | 956 | hdr->cmdsn, hdr->data_length, payload_length, conn->cid); |
958 | 957 | ||
959 | /* | 958 | cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd, |
960 | * The CDB is going to an se_device_t. | 959 | scsilun_to_int(&hdr->lun)); |
961 | */ | 960 | if (cmd->sense_reason) |
962 | ret = transport_lookup_cmd_lun(&cmd->se_cmd, | 961 | goto attach_cmd; |
963 | scsilun_to_int(&hdr->lun)); | 962 | |
964 | if (ret < 0) { | 963 | cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); |
965 | if (cmd->se_cmd.scsi_sense_reason == TCM_NON_EXISTENT_LUN) { | 964 | if (cmd->sense_reason) { |
966 | pr_debug("Responding to non-acl'ed," | 965 | if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) { |
967 | " non-existent or non-exported iSCSI LUN:" | 966 | return iscsit_add_reject_from_cmd( |
968 | " 0x%016Lx\n", get_unaligned_le64(&hdr->lun)); | 967 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
968 | 1, 1, buf, cmd); | ||
969 | } | 969 | } |
970 | send_check_condition = 1; | 970 | |
971 | goto attach_cmd; | 971 | goto attach_cmd; |
972 | } | 972 | } |
973 | 973 | ||
974 | transport_ret = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); | 974 | if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) { |
975 | if (transport_ret == -ENOMEM) { | ||
976 | return iscsit_add_reject_from_cmd( | 975 | return iscsit_add_reject_from_cmd( |
977 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 976 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
978 | 1, 1, buf, cmd); | 977 | 1, 1, buf, cmd); |
979 | } else if (transport_ret < 0) { | ||
980 | /* | ||
981 | * Unsupported SAM Opcode. CHECK_CONDITION will be sent | ||
982 | * in iscsit_execute_cmd() during the CmdSN OOO Execution | ||
983 | * Mechinism. | ||
984 | */ | ||
985 | send_check_condition = 1; | ||
986 | } else { | ||
987 | if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) | ||
988 | return iscsit_add_reject_from_cmd( | ||
989 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
990 | 1, 1, buf, cmd); | ||
991 | } | 978 | } |
992 | 979 | ||
993 | attach_cmd: | 980 | attach_cmd: |
@@ -1000,11 +987,12 @@ attach_cmd: | |||
1000 | */ | 987 | */ |
1001 | core_alua_check_nonop_delay(&cmd->se_cmd); | 988 | core_alua_check_nonop_delay(&cmd->se_cmd); |
1002 | 989 | ||
1003 | ret = iscsit_allocate_iovecs(cmd); | 990 | if (iscsit_allocate_iovecs(cmd) < 0) { |
1004 | if (ret < 0) | ||
1005 | return iscsit_add_reject_from_cmd( | 991 | return iscsit_add_reject_from_cmd( |
1006 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 992 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
1007 | 1, 0, buf, cmd); | 993 | 1, 0, buf, cmd); |
994 | } | ||
995 | |||
1008 | /* | 996 | /* |
1009 | * Check the CmdSN against ExpCmdSN/MaxCmdSN here if | 997 | * Check the CmdSN against ExpCmdSN/MaxCmdSN here if |
1010 | * the Immediate Bit is not set, and no Immediate | 998 | * the Immediate Bit is not set, and no Immediate |
@@ -1031,10 +1019,7 @@ attach_cmd: | |||
1031 | * If no Immediate Data is attached, it's OK to return now. | 1019 | * If no Immediate Data is attached, it's OK to return now. |
1032 | */ | 1020 | */ |
1033 | if (!cmd->immediate_data) { | 1021 | if (!cmd->immediate_data) { |
1034 | if (send_check_condition) | 1022 | if (!cmd->sense_reason && cmd->unsolicited_data) { |
1035 | return 0; | ||
1036 | |||
1037 | if (cmd->unsolicited_data) { | ||
1038 | iscsit_set_dataout_sequence_values(cmd); | 1023 | iscsit_set_dataout_sequence_values(cmd); |
1039 | 1024 | ||
1040 | spin_lock_bh(&cmd->dataout_timeout_lock); | 1025 | spin_lock_bh(&cmd->dataout_timeout_lock); |
@@ -1050,19 +1035,17 @@ attach_cmd: | |||
1050 | * thread. They are processed in CmdSN order by | 1035 | * thread. They are processed in CmdSN order by |
1051 | * iscsit_check_received_cmdsn() below. | 1036 | * iscsit_check_received_cmdsn() below. |
1052 | */ | 1037 | */ |
1053 | if (send_check_condition) { | 1038 | if (cmd->sense_reason) { |
1054 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; | 1039 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; |
1055 | dump_immediate_data = 1; | ||
1056 | goto after_immediate_data; | 1040 | goto after_immediate_data; |
1057 | } | 1041 | } |
1058 | /* | 1042 | /* |
1059 | * Call directly into transport_generic_new_cmd() to perform | 1043 | * Call directly into transport_generic_new_cmd() to perform |
1060 | * the backend memory allocation. | 1044 | * the backend memory allocation. |
1061 | */ | 1045 | */ |
1062 | ret = transport_generic_new_cmd(&cmd->se_cmd); | 1046 | cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd); |
1063 | if (ret < 0) { | 1047 | if (cmd->sense_reason) { |
1064 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; | 1048 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; |
1065 | dump_immediate_data = 1; | ||
1066 | goto after_immediate_data; | 1049 | goto after_immediate_data; |
1067 | } | 1050 | } |
1068 | 1051 | ||
@@ -1079,7 +1062,7 @@ after_immediate_data: | |||
1079 | * Special case for Unsupported SAM WRITE Opcodes | 1062 | * Special case for Unsupported SAM WRITE Opcodes |
1080 | * and ImmediateData=Yes. | 1063 | * and ImmediateData=Yes. |
1081 | */ | 1064 | */ |
1082 | if (dump_immediate_data) { | 1065 | if (cmd->sense_reason) { |
1083 | if (iscsit_dump_data_payload(conn, payload_length, 1) < 0) | 1066 | if (iscsit_dump_data_payload(conn, payload_length, 1) < 0) |
1084 | return -1; | 1067 | return -1; |
1085 | } else if (cmd->unsolicited_data) { | 1068 | } else if (cmd->unsolicited_data) { |
@@ -1272,8 +1255,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | |||
1272 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); | 1255 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); |
1273 | 1256 | ||
1274 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); | 1257 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); |
1275 | if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) || | 1258 | if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE)) |
1276 | (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION)) | ||
1277 | dump_unsolicited_data = 1; | 1259 | dump_unsolicited_data = 1; |
1278 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); | 1260 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); |
1279 | 1261 | ||
@@ -1742,7 +1724,6 @@ static int iscsit_handle_task_mgt_cmd( | |||
1742 | ret = transport_lookup_tmr_lun(&cmd->se_cmd, | 1724 | ret = transport_lookup_tmr_lun(&cmd->se_cmd, |
1743 | scsilun_to_int(&hdr->lun)); | 1725 | scsilun_to_int(&hdr->lun)); |
1744 | if (ret < 0) { | 1726 | if (ret < 0) { |
1745 | cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1746 | se_tmr->response = ISCSI_TMF_RSP_NO_LUN; | 1727 | se_tmr->response = ISCSI_TMF_RSP_NO_LUN; |
1747 | goto attach; | 1728 | goto attach; |
1748 | } | 1729 | } |
@@ -1751,10 +1732,8 @@ static int iscsit_handle_task_mgt_cmd( | |||
1751 | switch (function) { | 1732 | switch (function) { |
1752 | case ISCSI_TM_FUNC_ABORT_TASK: | 1733 | case ISCSI_TM_FUNC_ABORT_TASK: |
1753 | se_tmr->response = iscsit_tmr_abort_task(cmd, buf); | 1734 | se_tmr->response = iscsit_tmr_abort_task(cmd, buf); |
1754 | if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE) { | 1735 | if (se_tmr->response) |
1755 | cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1756 | goto attach; | 1736 | goto attach; |
1757 | } | ||
1758 | break; | 1737 | break; |
1759 | case ISCSI_TM_FUNC_ABORT_TASK_SET: | 1738 | case ISCSI_TM_FUNC_ABORT_TASK_SET: |
1760 | case ISCSI_TM_FUNC_CLEAR_ACA: | 1739 | case ISCSI_TM_FUNC_CLEAR_ACA: |
@@ -1763,14 +1742,12 @@ static int iscsit_handle_task_mgt_cmd( | |||
1763 | break; | 1742 | break; |
1764 | case ISCSI_TM_FUNC_TARGET_WARM_RESET: | 1743 | case ISCSI_TM_FUNC_TARGET_WARM_RESET: |
1765 | if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) { | 1744 | if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) { |
1766 | cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1767 | se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; | 1745 | se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; |
1768 | goto attach; | 1746 | goto attach; |
1769 | } | 1747 | } |
1770 | break; | 1748 | break; |
1771 | case ISCSI_TM_FUNC_TARGET_COLD_RESET: | 1749 | case ISCSI_TM_FUNC_TARGET_COLD_RESET: |
1772 | if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) { | 1750 | if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) { |
1773 | cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1774 | se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; | 1751 | se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; |
1775 | goto attach; | 1752 | goto attach; |
1776 | } | 1753 | } |
@@ -1781,7 +1758,7 @@ static int iscsit_handle_task_mgt_cmd( | |||
1781 | * Perform sanity checks on the ExpDataSN only if the | 1758 | * Perform sanity checks on the ExpDataSN only if the |
1782 | * TASK_REASSIGN was successful. | 1759 | * TASK_REASSIGN was successful. |
1783 | */ | 1760 | */ |
1784 | if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE) | 1761 | if (se_tmr->response) |
1785 | break; | 1762 | break; |
1786 | 1763 | ||
1787 | if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0) | 1764 | if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0) |
@@ -1792,7 +1769,6 @@ static int iscsit_handle_task_mgt_cmd( | |||
1792 | default: | 1769 | default: |
1793 | pr_err("Unknown TMR function: 0x%02x, protocol" | 1770 | pr_err("Unknown TMR function: 0x%02x, protocol" |
1794 | " error.\n", function); | 1771 | " error.\n", function); |
1795 | cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1796 | se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED; | 1772 | se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED; |
1797 | goto attach; | 1773 | goto attach; |
1798 | } | 1774 | } |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 21048dbf7d13..7a333d28d9a2 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -474,7 +474,7 @@ struct iscsi_cmd { | |||
474 | struct scatterlist *first_data_sg; | 474 | struct scatterlist *first_data_sg; |
475 | u32 first_data_sg_off; | 475 | u32 first_data_sg_off; |
476 | u32 kmapped_nents; | 476 | u32 kmapped_nents; |
477 | 477 | sense_reason_t sense_reason; | |
478 | } ____cacheline_aligned; | 478 | } ____cacheline_aligned; |
479 | 479 | ||
480 | struct iscsi_tmr_req { | 480 | struct iscsi_tmr_req { |
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index 21f29d91a8cb..0b52a2371305 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c | |||
@@ -929,11 +929,10 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) | |||
929 | case ISCSI_OP_SCSI_CMD: | 929 | case ISCSI_OP_SCSI_CMD: |
930 | /* | 930 | /* |
931 | * Go ahead and send the CHECK_CONDITION status for | 931 | * Go ahead and send the CHECK_CONDITION status for |
932 | * any SCSI CDB exceptions that may have occurred, also | 932 | * any SCSI CDB exceptions that may have occurred. |
933 | * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well. | ||
934 | */ | 933 | */ |
935 | if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { | 934 | if (cmd->sense_reason) { |
936 | if (se_cmd->scsi_sense_reason == TCM_RESERVATION_CONFLICT) { | 935 | if (cmd->sense_reason == TCM_RESERVATION_CONFLICT) { |
937 | cmd->i_state = ISTATE_SEND_STATUS; | 936 | cmd->i_state = ISTATE_SEND_STATUS; |
938 | spin_unlock_bh(&cmd->istate_lock); | 937 | spin_unlock_bh(&cmd->istate_lock); |
939 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, | 938 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, |
@@ -956,7 +955,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) | |||
956 | * exception | 955 | * exception |
957 | */ | 956 | */ |
958 | return transport_send_check_condition_and_sense(se_cmd, | 957 | return transport_send_check_condition_and_sense(se_cmd, |
959 | se_cmd->scsi_sense_reason, 0); | 958 | cmd->sense_reason, 0); |
960 | } | 959 | } |
961 | /* | 960 | /* |
962 | * Special case for delayed CmdSN with Immediate | 961 | * Special case for delayed CmdSN with Immediate |
@@ -1013,7 +1012,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) | |||
1013 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); | 1012 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); |
1014 | break; | 1013 | break; |
1015 | case ISCSI_OP_SCSI_TMFUNC: | 1014 | case ISCSI_OP_SCSI_TMFUNC: |
1016 | if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { | 1015 | if (cmd->se_cmd.se_tmr_req->response) { |
1017 | spin_unlock_bh(&cmd->istate_lock); | 1016 | spin_unlock_bh(&cmd->istate_lock); |
1018 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, | 1017 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, |
1019 | cmd->i_state); | 1018 | cmd->i_state); |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index b3302a9200a2..e62dc529e516 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include "target_core_alua.h" | 41 | #include "target_core_alua.h" |
42 | #include "target_core_ua.h" | 42 | #include "target_core_ua.h" |
43 | 43 | ||
44 | static int core_alua_check_transition(int state, int *primary); | 44 | static sense_reason_t core_alua_check_transition(int state, int *primary); |
45 | static int core_alua_set_tg_pt_secondary_state( | 45 | static int core_alua_set_tg_pt_secondary_state( |
46 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, | 46 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, |
47 | struct se_port *port, int explict, int offline); | 47 | struct se_port *port, int explict, int offline); |
@@ -59,7 +59,8 @@ struct t10_alua_lu_gp *default_lu_gp; | |||
59 | * | 59 | * |
60 | * See spc4r17 section 6.27 | 60 | * See spc4r17 section 6.27 |
61 | */ | 61 | */ |
62 | int target_emulate_report_target_port_groups(struct se_cmd *cmd) | 62 | sense_reason_t |
63 | target_emulate_report_target_port_groups(struct se_cmd *cmd) | ||
63 | { | 64 | { |
64 | struct se_device *dev = cmd->se_dev; | 65 | struct se_device *dev = cmd->se_dev; |
65 | struct se_port *port; | 66 | struct se_port *port; |
@@ -68,6 +69,7 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd) | |||
68 | unsigned char *buf; | 69 | unsigned char *buf; |
69 | u32 rd_len = 0, off; | 70 | u32 rd_len = 0, off; |
70 | int ext_hdr = (cmd->t_task_cdb[1] & 0x20); | 71 | int ext_hdr = (cmd->t_task_cdb[1] & 0x20); |
72 | |||
71 | /* | 73 | /* |
72 | * Skip over RESERVED area to first Target port group descriptor | 74 | * Skip over RESERVED area to first Target port group descriptor |
73 | * depending on the PARAMETER DATA FORMAT type.. | 75 | * depending on the PARAMETER DATA FORMAT type.. |
@@ -81,10 +83,11 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd) | |||
81 | pr_warn("REPORT TARGET PORT GROUPS allocation length %u too" | 83 | pr_warn("REPORT TARGET PORT GROUPS allocation length %u too" |
82 | " small for %s header\n", cmd->data_length, | 84 | " small for %s header\n", cmd->data_length, |
83 | (ext_hdr) ? "extended" : "normal"); | 85 | (ext_hdr) ? "extended" : "normal"); |
84 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 86 | return TCM_INVALID_CDB_FIELD; |
85 | return -EINVAL; | ||
86 | } | 87 | } |
87 | buf = transport_kmap_data_sg(cmd); | 88 | buf = transport_kmap_data_sg(cmd); |
89 | if (!buf) | ||
90 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
88 | 91 | ||
89 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); | 92 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
90 | list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list, | 93 | list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list, |
@@ -200,7 +203,8 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd) | |||
200 | * | 203 | * |
201 | * See spc4r17 section 6.35 | 204 | * See spc4r17 section 6.35 |
202 | */ | 205 | */ |
203 | int target_emulate_set_target_port_groups(struct se_cmd *cmd) | 206 | sense_reason_t |
207 | target_emulate_set_target_port_groups(struct se_cmd *cmd) | ||
204 | { | 208 | { |
205 | struct se_device *dev = cmd->se_dev; | 209 | struct se_device *dev = cmd->se_dev; |
206 | struct se_port *port, *l_port = cmd->se_lun->lun_sep; | 210 | struct se_port *port, *l_port = cmd->se_lun->lun_sep; |
@@ -209,22 +213,23 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
209 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *l_tg_pt_gp_mem; | 213 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *l_tg_pt_gp_mem; |
210 | unsigned char *buf; | 214 | unsigned char *buf; |
211 | unsigned char *ptr; | 215 | unsigned char *ptr; |
216 | sense_reason_t rc; | ||
212 | u32 len = 4; /* Skip over RESERVED area in header */ | 217 | u32 len = 4; /* Skip over RESERVED area in header */ |
213 | int alua_access_state, primary = 0, rc; | 218 | int alua_access_state, primary = 0; |
214 | u16 tg_pt_id, rtpi; | 219 | u16 tg_pt_id, rtpi; |
215 | 220 | ||
216 | if (!l_port) { | 221 | if (!l_port) |
217 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 222 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
218 | return -EINVAL; | 223 | |
219 | } | ||
220 | if (cmd->data_length < 4) { | 224 | if (cmd->data_length < 4) { |
221 | pr_warn("SET TARGET PORT GROUPS parameter list length %u too" | 225 | pr_warn("SET TARGET PORT GROUPS parameter list length %u too" |
222 | " small\n", cmd->data_length); | 226 | " small\n", cmd->data_length); |
223 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 227 | return TCM_INVALID_PARAMETER_LIST; |
224 | return -EINVAL; | ||
225 | } | 228 | } |
226 | 229 | ||
227 | buf = transport_kmap_data_sg(cmd); | 230 | buf = transport_kmap_data_sg(cmd); |
231 | if (!buf) | ||
232 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
228 | 233 | ||
229 | /* | 234 | /* |
230 | * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed | 235 | * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed |
@@ -233,8 +238,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
233 | l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; | 238 | l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; |
234 | if (!l_tg_pt_gp_mem) { | 239 | if (!l_tg_pt_gp_mem) { |
235 | pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); | 240 | pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); |
236 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 241 | rc = TCM_UNSUPPORTED_SCSI_OPCODE; |
237 | rc = -EINVAL; | ||
238 | goto out; | 242 | goto out; |
239 | } | 243 | } |
240 | spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 244 | spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
@@ -242,24 +246,22 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
242 | if (!l_tg_pt_gp) { | 246 | if (!l_tg_pt_gp) { |
243 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 247 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
244 | pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); | 248 | pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); |
245 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 249 | rc = TCM_UNSUPPORTED_SCSI_OPCODE; |
246 | rc = -EINVAL; | ||
247 | goto out; | 250 | goto out; |
248 | } | 251 | } |
249 | rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA); | ||
250 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 252 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
251 | 253 | ||
252 | if (!rc) { | 254 | if (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA) { |
253 | pr_debug("Unable to process SET_TARGET_PORT_GROUPS" | 255 | pr_debug("Unable to process SET_TARGET_PORT_GROUPS" |
254 | " while TPGS_EXPLICT_ALUA is disabled\n"); | 256 | " while TPGS_EXPLICT_ALUA is disabled\n"); |
255 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 257 | rc = TCM_UNSUPPORTED_SCSI_OPCODE; |
256 | rc = -EINVAL; | ||
257 | goto out; | 258 | goto out; |
258 | } | 259 | } |
259 | 260 | ||
260 | ptr = &buf[4]; /* Skip over RESERVED area in header */ | 261 | ptr = &buf[4]; /* Skip over RESERVED area in header */ |
261 | 262 | ||
262 | while (len < cmd->data_length) { | 263 | while (len < cmd->data_length) { |
264 | bool found = false; | ||
263 | alua_access_state = (ptr[0] & 0x0f); | 265 | alua_access_state = (ptr[0] & 0x0f); |
264 | /* | 266 | /* |
265 | * Check the received ALUA access state, and determine if | 267 | * Check the received ALUA access state, and determine if |
@@ -267,7 +269,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
267 | * access state. | 269 | * access state. |
268 | */ | 270 | */ |
269 | rc = core_alua_check_transition(alua_access_state, &primary); | 271 | rc = core_alua_check_transition(alua_access_state, &primary); |
270 | if (rc != 0) { | 272 | if (rc) { |
271 | /* | 273 | /* |
272 | * If the SET TARGET PORT GROUPS attempts to establish | 274 | * If the SET TARGET PORT GROUPS attempts to establish |
273 | * an invalid combination of target port asymmetric | 275 | * an invalid combination of target port asymmetric |
@@ -278,11 +280,9 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
278 | * REQUEST, and the additional sense code set to INVALID | 280 | * REQUEST, and the additional sense code set to INVALID |
279 | * FIELD IN PARAMETER LIST. | 281 | * FIELD IN PARAMETER LIST. |
280 | */ | 282 | */ |
281 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
282 | rc = -EINVAL; | ||
283 | goto out; | 283 | goto out; |
284 | } | 284 | } |
285 | rc = -1; | 285 | |
286 | /* | 286 | /* |
287 | * If the ASYMMETRIC ACCESS STATE field (see table 267) | 287 | * If the ASYMMETRIC ACCESS STATE field (see table 267) |
288 | * specifies a primary target port asymmetric access state, | 288 | * specifies a primary target port asymmetric access state, |
@@ -314,11 +314,13 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
314 | 314 | ||
315 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); | 315 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); |
316 | smp_mb__after_atomic_inc(); | 316 | smp_mb__after_atomic_inc(); |
317 | |||
317 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); | 318 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
318 | 319 | ||
319 | rc = core_alua_do_port_transition(tg_pt_gp, | 320 | if (!core_alua_do_port_transition(tg_pt_gp, |
320 | dev, l_port, nacl, | 321 | dev, l_port, nacl, |
321 | alua_access_state, 1); | 322 | alua_access_state, 1)) |
323 | found = true; | ||
322 | 324 | ||
323 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); | 325 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
324 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); | 326 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); |
@@ -326,15 +328,6 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
326 | break; | 328 | break; |
327 | } | 329 | } |
328 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); | 330 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
329 | /* | ||
330 | * If not matching target port group ID can be located | ||
331 | * throw an exception with ASCQ: INVALID_PARAMETER_LIST | ||
332 | */ | ||
333 | if (rc != 0) { | ||
334 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
335 | rc = -EINVAL; | ||
336 | goto out; | ||
337 | } | ||
338 | } else { | 331 | } else { |
339 | /* | 332 | /* |
340 | * Extact the RELATIVE TARGET PORT IDENTIFIER to identify | 333 | * Extact the RELATIVE TARGET PORT IDENTIFIER to identify |
@@ -353,25 +346,22 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
353 | continue; | 346 | continue; |
354 | 347 | ||
355 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; | 348 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; |
349 | |||
356 | spin_unlock(&dev->se_port_lock); | 350 | spin_unlock(&dev->se_port_lock); |
357 | 351 | ||
358 | rc = core_alua_set_tg_pt_secondary_state( | 352 | if (!core_alua_set_tg_pt_secondary_state( |
359 | tg_pt_gp_mem, port, 1, 1); | 353 | tg_pt_gp_mem, port, 1, 1)) |
354 | found = true; | ||
360 | 355 | ||
361 | spin_lock(&dev->se_port_lock); | 356 | spin_lock(&dev->se_port_lock); |
362 | break; | 357 | break; |
363 | } | 358 | } |
364 | spin_unlock(&dev->se_port_lock); | 359 | spin_unlock(&dev->se_port_lock); |
365 | /* | 360 | } |
366 | * If not matching relative target port identifier can | 361 | |
367 | * be located, throw an exception with ASCQ: | 362 | if (!found) { |
368 | * INVALID_PARAMETER_LIST | 363 | rc = TCM_INVALID_PARAMETER_LIST; |
369 | */ | 364 | goto out; |
370 | if (rc != 0) { | ||
371 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
372 | rc = -EINVAL; | ||
373 | goto out; | ||
374 | } | ||
375 | } | 365 | } |
376 | 366 | ||
377 | ptr += 4; | 367 | ptr += 4; |
@@ -526,7 +516,8 @@ static inline int core_alua_state_transition( | |||
526 | * return 0: Used to signal success | 516 | * return 0: Used to signal success |
527 | * reutrn -1: Used to signal failure, and invalid cdb field | 517 | * reutrn -1: Used to signal failure, and invalid cdb field |
528 | */ | 518 | */ |
529 | int target_alua_state_check(struct se_cmd *cmd) | 519 | sense_reason_t |
520 | target_alua_state_check(struct se_cmd *cmd) | ||
530 | { | 521 | { |
531 | struct se_device *dev = cmd->se_dev; | 522 | struct se_device *dev = cmd->se_dev; |
532 | unsigned char *cdb = cmd->t_task_cdb; | 523 | unsigned char *cdb = cmd->t_task_cdb; |
@@ -599,8 +590,7 @@ int target_alua_state_check(struct se_cmd *cmd) | |||
599 | default: | 590 | default: |
600 | pr_err("Unknown ALUA access state: 0x%02x\n", | 591 | pr_err("Unknown ALUA access state: 0x%02x\n", |
601 | out_alua_state); | 592 | out_alua_state); |
602 | ret = -EINVAL; | 593 | return TCM_INVALID_CDB_FIELD; |
603 | break; | ||
604 | } | 594 | } |
605 | 595 | ||
606 | out: | 596 | out: |
@@ -617,15 +607,17 @@ out: | |||
617 | 607 | ||
618 | cmd->scsi_asc = 0x04; | 608 | cmd->scsi_asc = 0x04; |
619 | cmd->scsi_ascq = alua_ascq; | 609 | cmd->scsi_ascq = alua_ascq; |
610 | return TCM_CHECK_CONDITION_NOT_READY; | ||
620 | } | 611 | } |
621 | 612 | ||
622 | return ret; | 613 | return 0; |
623 | } | 614 | } |
624 | 615 | ||
625 | /* | 616 | /* |
626 | * Check implict and explict ALUA state change request. | 617 | * Check implict and explict ALUA state change request. |
627 | */ | 618 | */ |
628 | static int core_alua_check_transition(int state, int *primary) | 619 | static sense_reason_t |
620 | core_alua_check_transition(int state, int *primary) | ||
629 | { | 621 | { |
630 | switch (state) { | 622 | switch (state) { |
631 | case ALUA_ACCESS_STATE_ACTIVE_OPTMIZED: | 623 | case ALUA_ACCESS_STATE_ACTIVE_OPTMIZED: |
@@ -647,7 +639,7 @@ static int core_alua_check_transition(int state, int *primary) | |||
647 | break; | 639 | break; |
648 | default: | 640 | default: |
649 | pr_err("Unknown ALUA access state: 0x%02x\n", state); | 641 | pr_err("Unknown ALUA access state: 0x%02x\n", state); |
650 | return -EINVAL; | 642 | return TCM_INVALID_PARAMETER_LIST; |
651 | } | 643 | } |
652 | 644 | ||
653 | return 0; | 645 | return 0; |
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h index a2af8aa15b98..e539c3e7f4ad 100644 --- a/drivers/target/target_core_alua.h +++ b/drivers/target/target_core_alua.h | |||
@@ -72,8 +72,8 @@ extern struct kmem_cache *t10_alua_lu_gp_mem_cache; | |||
72 | extern struct kmem_cache *t10_alua_tg_pt_gp_cache; | 72 | extern struct kmem_cache *t10_alua_tg_pt_gp_cache; |
73 | extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache; | 73 | extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache; |
74 | 74 | ||
75 | extern int target_emulate_report_target_port_groups(struct se_cmd *); | 75 | extern sense_reason_t target_emulate_report_target_port_groups(struct se_cmd *); |
76 | extern int target_emulate_set_target_port_groups(struct se_cmd *); | 76 | extern sense_reason_t target_emulate_set_target_port_groups(struct se_cmd *); |
77 | extern int core_alua_check_nonop_delay(struct se_cmd *); | 77 | extern int core_alua_check_nonop_delay(struct se_cmd *); |
78 | extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *, | 78 | extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *, |
79 | struct se_device *, struct se_port *, | 79 | struct se_device *, struct se_port *, |
@@ -132,6 +132,6 @@ extern ssize_t core_alua_show_secondary_write_metadata(struct se_lun *, | |||
132 | extern ssize_t core_alua_store_secondary_write_metadata(struct se_lun *, | 132 | extern ssize_t core_alua_store_secondary_write_metadata(struct se_lun *, |
133 | const char *, size_t); | 133 | const char *, size_t); |
134 | extern int core_setup_alua(struct se_device *); | 134 | extern int core_setup_alua(struct se_device *); |
135 | extern int target_alua_state_check(struct se_cmd *cmd); | 135 | extern sense_reason_t target_alua_state_check(struct se_cmd *cmd); |
136 | 136 | ||
137 | #endif /* TARGET_CORE_ALUA_H */ | 137 | #endif /* TARGET_CORE_ALUA_H */ |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 066e8159afcd..599374e6d245 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -54,18 +54,16 @@ static struct se_hba *lun0_hba; | |||
54 | /* not static, needed by tpg.c */ | 54 | /* not static, needed by tpg.c */ |
55 | struct se_device *g_lun0_dev; | 55 | struct se_device *g_lun0_dev; |
56 | 56 | ||
57 | int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | 57 | sense_reason_t |
58 | transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | ||
58 | { | 59 | { |
59 | struct se_lun *se_lun = NULL; | 60 | struct se_lun *se_lun = NULL; |
60 | struct se_session *se_sess = se_cmd->se_sess; | 61 | struct se_session *se_sess = se_cmd->se_sess; |
61 | struct se_device *dev; | 62 | struct se_device *dev; |
62 | unsigned long flags; | 63 | unsigned long flags; |
63 | 64 | ||
64 | if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) { | 65 | if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) |
65 | se_cmd->scsi_sense_reason = TCM_NON_EXISTENT_LUN; | 66 | return TCM_NON_EXISTENT_LUN; |
66 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
67 | return -ENODEV; | ||
68 | } | ||
69 | 67 | ||
70 | spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); | 68 | spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); |
71 | se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; | 69 | se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; |
@@ -77,14 +75,12 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
77 | 75 | ||
78 | if ((se_cmd->data_direction == DMA_TO_DEVICE) && | 76 | if ((se_cmd->data_direction == DMA_TO_DEVICE) && |
79 | (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { | 77 | (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { |
80 | se_cmd->scsi_sense_reason = TCM_WRITE_PROTECTED; | ||
81 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
82 | pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" | 78 | pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" |
83 | " Access for 0x%08x\n", | 79 | " Access for 0x%08x\n", |
84 | se_cmd->se_tfo->get_fabric_name(), | 80 | se_cmd->se_tfo->get_fabric_name(), |
85 | unpacked_lun); | 81 | unpacked_lun); |
86 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); | 82 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); |
87 | return -EACCES; | 83 | return TCM_WRITE_PROTECTED; |
88 | } | 84 | } |
89 | 85 | ||
90 | if (se_cmd->data_direction == DMA_TO_DEVICE) | 86 | if (se_cmd->data_direction == DMA_TO_DEVICE) |
@@ -109,23 +105,18 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
109 | * MappedLUN=0 exists for this Initiator Port. | 105 | * MappedLUN=0 exists for this Initiator Port. |
110 | */ | 106 | */ |
111 | if (unpacked_lun != 0) { | 107 | if (unpacked_lun != 0) { |
112 | se_cmd->scsi_sense_reason = TCM_NON_EXISTENT_LUN; | ||
113 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
114 | pr_err("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" | 108 | pr_err("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" |
115 | " Access for 0x%08x\n", | 109 | " Access for 0x%08x\n", |
116 | se_cmd->se_tfo->get_fabric_name(), | 110 | se_cmd->se_tfo->get_fabric_name(), |
117 | unpacked_lun); | 111 | unpacked_lun); |
118 | return -ENODEV; | 112 | return TCM_NON_EXISTENT_LUN; |
119 | } | 113 | } |
120 | /* | 114 | /* |
121 | * Force WRITE PROTECT for virtual LUN 0 | 115 | * Force WRITE PROTECT for virtual LUN 0 |
122 | */ | 116 | */ |
123 | if ((se_cmd->data_direction != DMA_FROM_DEVICE) && | 117 | if ((se_cmd->data_direction != DMA_FROM_DEVICE) && |
124 | (se_cmd->data_direction != DMA_NONE)) { | 118 | (se_cmd->data_direction != DMA_NONE)) |
125 | se_cmd->scsi_sense_reason = TCM_WRITE_PROTECTED; | 119 | return TCM_WRITE_PROTECTED; |
126 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
127 | return -EACCES; | ||
128 | } | ||
129 | 120 | ||
130 | se_lun = &se_sess->se_tpg->tpg_virt_lun0; | 121 | se_lun = &se_sess->se_tpg->tpg_virt_lun0; |
131 | se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0; | 122 | se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0; |
@@ -162,11 +153,8 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
162 | struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; | 153 | struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; |
163 | unsigned long flags; | 154 | unsigned long flags; |
164 | 155 | ||
165 | if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) { | 156 | if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) |
166 | se_cmd->scsi_sense_reason = TCM_NON_EXISTENT_LUN; | ||
167 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
168 | return -ENODEV; | 157 | return -ENODEV; |
169 | } | ||
170 | 158 | ||
171 | spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); | 159 | spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); |
172 | se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; | 160 | se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; |
@@ -186,7 +174,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
186 | " Access for 0x%08x\n", | 174 | " Access for 0x%08x\n", |
187 | se_cmd->se_tfo->get_fabric_name(), | 175 | se_cmd->se_tfo->get_fabric_name(), |
188 | unpacked_lun); | 176 | unpacked_lun); |
189 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
190 | return -ENODEV; | 177 | return -ENODEV; |
191 | } | 178 | } |
192 | 179 | ||
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 342a6a6dcca0..3ccef831a641 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
@@ -309,7 +309,8 @@ static int fd_do_writev(struct se_cmd *cmd, struct scatterlist *sgl, | |||
309 | return 1; | 309 | return 1; |
310 | } | 310 | } |
311 | 311 | ||
312 | static int fd_execute_sync_cache(struct se_cmd *cmd) | 312 | static sense_reason_t |
313 | fd_execute_sync_cache(struct se_cmd *cmd) | ||
313 | { | 314 | { |
314 | struct se_device *dev = cmd->se_dev; | 315 | struct se_device *dev = cmd->se_dev; |
315 | struct fd_dev *fd_dev = FD_DEV(dev); | 316 | struct fd_dev *fd_dev = FD_DEV(dev); |
@@ -345,17 +346,16 @@ static int fd_execute_sync_cache(struct se_cmd *cmd) | |||
345 | if (immed) | 346 | if (immed) |
346 | return 0; | 347 | return 0; |
347 | 348 | ||
348 | if (ret) { | 349 | if (ret) |
349 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
350 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); | 350 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); |
351 | } else { | 351 | else |
352 | target_complete_cmd(cmd, SAM_STAT_GOOD); | 352 | target_complete_cmd(cmd, SAM_STAT_GOOD); |
353 | } | ||
354 | 353 | ||
355 | return 0; | 354 | return 0; |
356 | } | 355 | } |
357 | 356 | ||
358 | static int fd_execute_rw(struct se_cmd *cmd) | 357 | static sense_reason_t |
358 | fd_execute_rw(struct se_cmd *cmd) | ||
359 | { | 359 | { |
360 | struct scatterlist *sgl = cmd->t_data_sg; | 360 | struct scatterlist *sgl = cmd->t_data_sg; |
361 | u32 sgl_nents = cmd->t_data_nents; | 361 | u32 sgl_nents = cmd->t_data_nents; |
@@ -388,10 +388,9 @@ static int fd_execute_rw(struct se_cmd *cmd) | |||
388 | } | 388 | } |
389 | } | 389 | } |
390 | 390 | ||
391 | if (ret < 0) { | 391 | if (ret < 0) |
392 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 392 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
393 | return ret; | 393 | |
394 | } | ||
395 | if (ret) | 394 | if (ret) |
396 | target_complete_cmd(cmd, SAM_STAT_GOOD); | 395 | target_complete_cmd(cmd, SAM_STAT_GOOD); |
397 | return 0; | 396 | return 0; |
@@ -515,7 +514,8 @@ static struct sbc_ops fd_sbc_ops = { | |||
515 | .execute_sync_cache = fd_execute_sync_cache, | 514 | .execute_sync_cache = fd_execute_sync_cache, |
516 | }; | 515 | }; |
517 | 516 | ||
518 | static int fd_parse_cdb(struct se_cmd *cmd) | 517 | static sense_reason_t |
518 | fd_parse_cdb(struct se_cmd *cmd) | ||
519 | { | 519 | { |
520 | return sbc_parse_cdb(cmd, &fd_sbc_ops); | 520 | return sbc_parse_cdb(cmd, &fd_sbc_ops); |
521 | } | 521 | } |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 17fc01d6baea..53f4501819f9 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -261,13 +261,10 @@ static void iblock_end_io_flush(struct bio *bio, int err) | |||
261 | pr_err("IBLOCK: cache flush failed: %d\n", err); | 261 | pr_err("IBLOCK: cache flush failed: %d\n", err); |
262 | 262 | ||
263 | if (cmd) { | 263 | if (cmd) { |
264 | if (err) { | 264 | if (err) |
265 | cmd->scsi_sense_reason = | ||
266 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
267 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); | 265 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); |
268 | } else { | 266 | else |
269 | target_complete_cmd(cmd, SAM_STAT_GOOD); | 267 | target_complete_cmd(cmd, SAM_STAT_GOOD); |
270 | } | ||
271 | } | 268 | } |
272 | 269 | ||
273 | bio_put(bio); | 270 | bio_put(bio); |
@@ -277,7 +274,8 @@ static void iblock_end_io_flush(struct bio *bio, int err) | |||
277 | * Implement SYCHRONIZE CACHE. Note that we can't handle lba ranges and must | 274 | * Implement SYCHRONIZE CACHE. Note that we can't handle lba ranges and must |
278 | * always flush the whole cache. | 275 | * always flush the whole cache. |
279 | */ | 276 | */ |
280 | static int iblock_execute_sync_cache(struct se_cmd *cmd) | 277 | static sense_reason_t |
278 | iblock_execute_sync_cache(struct se_cmd *cmd) | ||
281 | { | 279 | { |
282 | struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev); | 280 | struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev); |
283 | int immed = (cmd->t_task_cdb[1] & 0x2); | 281 | int immed = (cmd->t_task_cdb[1] & 0x2); |
@@ -299,7 +297,8 @@ static int iblock_execute_sync_cache(struct se_cmd *cmd) | |||
299 | return 0; | 297 | return 0; |
300 | } | 298 | } |
301 | 299 | ||
302 | static int iblock_execute_unmap(struct se_cmd *cmd) | 300 | static sense_reason_t |
301 | iblock_execute_unmap(struct se_cmd *cmd) | ||
303 | { | 302 | { |
304 | struct se_device *dev = cmd->se_dev; | 303 | struct se_device *dev = cmd->se_dev; |
305 | struct iblock_dev *ib_dev = IBLOCK_DEV(dev); | 304 | struct iblock_dev *ib_dev = IBLOCK_DEV(dev); |
@@ -307,17 +306,18 @@ static int iblock_execute_unmap(struct se_cmd *cmd) | |||
307 | sector_t lba; | 306 | sector_t lba; |
308 | int size; | 307 | int size; |
309 | u32 range; | 308 | u32 range; |
310 | int ret = 0; | 309 | sense_reason_t ret = 0; |
311 | int dl, bd_dl; | 310 | int dl, bd_dl, err; |
312 | 311 | ||
313 | if (cmd->data_length < 8) { | 312 | if (cmd->data_length < 8) { |
314 | pr_warn("UNMAP parameter list length %u too small\n", | 313 | pr_warn("UNMAP parameter list length %u too small\n", |
315 | cmd->data_length); | 314 | cmd->data_length); |
316 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 315 | return TCM_INVALID_PARAMETER_LIST; |
317 | return -EINVAL; | ||
318 | } | 316 | } |
319 | 317 | ||
320 | buf = transport_kmap_data_sg(cmd); | 318 | buf = transport_kmap_data_sg(cmd); |
319 | if (!buf) | ||
320 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
321 | 321 | ||
322 | dl = get_unaligned_be16(&buf[0]); | 322 | dl = get_unaligned_be16(&buf[0]); |
323 | bd_dl = get_unaligned_be16(&buf[2]); | 323 | bd_dl = get_unaligned_be16(&buf[2]); |
@@ -330,8 +330,7 @@ static int iblock_execute_unmap(struct se_cmd *cmd) | |||
330 | size = bd_dl; | 330 | size = bd_dl; |
331 | 331 | ||
332 | if (size / 16 > dev->dev_attrib.max_unmap_block_desc_count) { | 332 | if (size / 16 > dev->dev_attrib.max_unmap_block_desc_count) { |
333 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 333 | ret = TCM_INVALID_PARAMETER_LIST; |
334 | ret = -EINVAL; | ||
335 | goto err; | 334 | goto err; |
336 | } | 335 | } |
337 | 336 | ||
@@ -347,22 +346,21 @@ static int iblock_execute_unmap(struct se_cmd *cmd) | |||
347 | (unsigned long long)lba, range); | 346 | (unsigned long long)lba, range); |
348 | 347 | ||
349 | if (range > dev->dev_attrib.max_unmap_lba_count) { | 348 | if (range > dev->dev_attrib.max_unmap_lba_count) { |
350 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 349 | ret = TCM_INVALID_PARAMETER_LIST; |
351 | ret = -EINVAL; | ||
352 | goto err; | 350 | goto err; |
353 | } | 351 | } |
354 | 352 | ||
355 | if (lba + range > dev->transport->get_blocks(dev) + 1) { | 353 | if (lba + range > dev->transport->get_blocks(dev) + 1) { |
356 | cmd->scsi_sense_reason = TCM_ADDRESS_OUT_OF_RANGE; | 354 | ret = TCM_ADDRESS_OUT_OF_RANGE; |
357 | ret = -EINVAL; | ||
358 | goto err; | 355 | goto err; |
359 | } | 356 | } |
360 | 357 | ||
361 | ret = blkdev_issue_discard(ib_dev->ibd_bd, lba, range, | 358 | err = blkdev_issue_discard(ib_dev->ibd_bd, lba, range, |
362 | GFP_KERNEL, 0); | 359 | GFP_KERNEL, 0); |
363 | if (ret < 0) { | 360 | if (err < 0) { |
364 | pr_err("blkdev_issue_discard() failed: %d\n", | 361 | pr_err("blkdev_issue_discard() failed: %d\n", |
365 | ret); | 362 | err); |
363 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
366 | goto err; | 364 | goto err; |
367 | } | 365 | } |
368 | 366 | ||
@@ -377,7 +375,8 @@ err: | |||
377 | return ret; | 375 | return ret; |
378 | } | 376 | } |
379 | 377 | ||
380 | static int iblock_execute_write_same(struct se_cmd *cmd) | 378 | static sense_reason_t |
379 | iblock_execute_write_same(struct se_cmd *cmd) | ||
381 | { | 380 | { |
382 | struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev); | 381 | struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev); |
383 | int ret; | 382 | int ret; |
@@ -387,7 +386,7 @@ static int iblock_execute_write_same(struct se_cmd *cmd) | |||
387 | 0); | 386 | 0); |
388 | if (ret < 0) { | 387 | if (ret < 0) { |
389 | pr_debug("blkdev_issue_discard() failed for WRITE_SAME\n"); | 388 | pr_debug("blkdev_issue_discard() failed for WRITE_SAME\n"); |
390 | return ret; | 389 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
391 | } | 390 | } |
392 | 391 | ||
393 | target_complete_cmd(cmd, GOOD); | 392 | target_complete_cmd(cmd, GOOD); |
@@ -552,7 +551,8 @@ static void iblock_submit_bios(struct bio_list *list, int rw) | |||
552 | blk_finish_plug(&plug); | 551 | blk_finish_plug(&plug); |
553 | } | 552 | } |
554 | 553 | ||
555 | static int iblock_execute_rw(struct se_cmd *cmd) | 554 | static sense_reason_t |
555 | iblock_execute_rw(struct se_cmd *cmd) | ||
556 | { | 556 | { |
557 | struct scatterlist *sgl = cmd->t_data_sg; | 557 | struct scatterlist *sgl = cmd->t_data_sg; |
558 | u32 sgl_nents = cmd->t_data_nents; | 558 | u32 sgl_nents = cmd->t_data_nents; |
@@ -598,8 +598,7 @@ static int iblock_execute_rw(struct se_cmd *cmd) | |||
598 | else { | 598 | else { |
599 | pr_err("Unsupported SCSI -> BLOCK LBA conversion:" | 599 | pr_err("Unsupported SCSI -> BLOCK LBA conversion:" |
600 | " %u\n", dev->dev_attrib.block_size); | 600 | " %u\n", dev->dev_attrib.block_size); |
601 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 601 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
602 | return -ENOSYS; | ||
603 | } | 602 | } |
604 | 603 | ||
605 | ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); | 604 | ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); |
@@ -659,9 +658,8 @@ fail_put_bios: | |||
659 | bio_put(bio); | 658 | bio_put(bio); |
660 | fail_free_ibr: | 659 | fail_free_ibr: |
661 | kfree(ibr); | 660 | kfree(ibr); |
662 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
663 | fail: | 661 | fail: |
664 | return -ENOMEM; | 662 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
665 | } | 663 | } |
666 | 664 | ||
667 | static sector_t iblock_get_blocks(struct se_device *dev) | 665 | static sector_t iblock_get_blocks(struct se_device *dev) |
@@ -706,7 +704,8 @@ static struct sbc_ops iblock_sbc_ops = { | |||
706 | .execute_unmap = iblock_execute_unmap, | 704 | .execute_unmap = iblock_execute_unmap, |
707 | }; | 705 | }; |
708 | 706 | ||
709 | static int iblock_parse_cdb(struct se_cmd *cmd) | 707 | static sense_reason_t |
708 | iblock_parse_cdb(struct se_cmd *cmd) | ||
710 | { | 709 | { |
711 | return sbc_parse_cdb(cmd, &iblock_sbc_ops); | 710 | return sbc_parse_cdb(cmd, &iblock_sbc_ops); |
712 | } | 711 | } |
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 2f37720c4db3..bc9c52284845 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h | |||
@@ -101,7 +101,7 @@ int transport_dump_vpd_ident(struct t10_vpd *, unsigned char *, int); | |||
101 | bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags); | 101 | bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags); |
102 | int transport_clear_lun_from_sessions(struct se_lun *); | 102 | int transport_clear_lun_from_sessions(struct se_lun *); |
103 | void transport_send_task_abort(struct se_cmd *); | 103 | void transport_send_task_abort(struct se_cmd *); |
104 | int target_cmd_size_check(struct se_cmd *cmd, unsigned int size); | 104 | sense_reason_t target_cmd_size_check(struct se_cmd *cmd, unsigned int size); |
105 | void target_qf_do_work(struct work_struct *work); | 105 | void target_qf_do_work(struct work_struct *work); |
106 | 106 | ||
107 | /* target_core_stat.c */ | 107 | /* target_core_stat.c */ |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index f561a08ff8e5..ffbe0ea9bbad 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -68,7 +68,8 @@ int core_pr_dump_initiator_port( | |||
68 | static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, | 68 | static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, |
69 | struct t10_pr_registration *, int); | 69 | struct t10_pr_registration *, int); |
70 | 70 | ||
71 | static int target_scsi2_reservation_check(struct se_cmd *cmd) | 71 | static sense_reason_t |
72 | target_scsi2_reservation_check(struct se_cmd *cmd) | ||
72 | { | 73 | { |
73 | struct se_device *dev = cmd->se_dev; | 74 | struct se_device *dev = cmd->se_dev; |
74 | struct se_session *sess = cmd->se_sess; | 75 | struct se_session *sess = cmd->se_sess; |
@@ -86,11 +87,11 @@ static int target_scsi2_reservation_check(struct se_cmd *cmd) | |||
86 | return 0; | 87 | return 0; |
87 | 88 | ||
88 | if (dev->dev_reserved_node_acl != sess->se_node_acl) | 89 | if (dev->dev_reserved_node_acl != sess->se_node_acl) |
89 | return -EBUSY; | 90 | return TCM_RESERVATION_CONFLICT; |
90 | 91 | ||
91 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) { | 92 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) { |
92 | if (dev->dev_res_bin_isid != sess->sess_bin_isid) | 93 | if (dev->dev_res_bin_isid != sess->sess_bin_isid) |
93 | return -EBUSY; | 94 | return TCM_RESERVATION_CONFLICT; |
94 | } | 95 | } |
95 | 96 | ||
96 | return 0; | 97 | return 0; |
@@ -165,32 +166,28 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) | |||
165 | pr_err("Received legacy SPC-2 RESERVE/RELEASE" | 166 | pr_err("Received legacy SPC-2 RESERVE/RELEASE" |
166 | " while active SPC-3 registrations exist," | 167 | " while active SPC-3 registrations exist," |
167 | " returning RESERVATION_CONFLICT\n"); | 168 | " returning RESERVATION_CONFLICT\n"); |
168 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
169 | return -EBUSY; | 169 | return -EBUSY; |
170 | } | 170 | } |
171 | 171 | ||
172 | return 0; | 172 | return 0; |
173 | } | 173 | } |
174 | 174 | ||
175 | int target_scsi2_reservation_release(struct se_cmd *cmd) | 175 | sense_reason_t |
176 | target_scsi2_reservation_release(struct se_cmd *cmd) | ||
176 | { | 177 | { |
177 | struct se_device *dev = cmd->se_dev; | 178 | struct se_device *dev = cmd->se_dev; |
178 | struct se_session *sess = cmd->se_sess; | 179 | struct se_session *sess = cmd->se_sess; |
179 | struct se_portal_group *tpg; | 180 | struct se_portal_group *tpg; |
180 | int ret = 0, rc; | 181 | int rc; |
181 | 182 | ||
182 | if (!sess || !sess->se_tpg) | 183 | if (!sess || !sess->se_tpg) |
183 | goto out; | 184 | goto out; |
184 | rc = target_check_scsi2_reservation_conflict(cmd); | 185 | rc = target_check_scsi2_reservation_conflict(cmd); |
185 | if (rc == 1) | 186 | if (rc == 1) |
186 | goto out; | 187 | goto out; |
187 | else if (rc < 0) { | 188 | if (rc < 0) |
188 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 189 | return TCM_RESERVATION_CONFLICT; |
189 | ret = -EINVAL; | ||
190 | goto out; | ||
191 | } | ||
192 | 190 | ||
193 | ret = 0; | ||
194 | spin_lock(&dev->dev_reservation_lock); | 191 | spin_lock(&dev->dev_reservation_lock); |
195 | if (!dev->dev_reserved_node_acl || !sess) | 192 | if (!dev->dev_reserved_node_acl || !sess) |
196 | goto out_unlock; | 193 | goto out_unlock; |
@@ -216,25 +213,24 @@ int target_scsi2_reservation_release(struct se_cmd *cmd) | |||
216 | out_unlock: | 213 | out_unlock: |
217 | spin_unlock(&dev->dev_reservation_lock); | 214 | spin_unlock(&dev->dev_reservation_lock); |
218 | out: | 215 | out: |
219 | if (!ret) | 216 | target_complete_cmd(cmd, GOOD); |
220 | target_complete_cmd(cmd, GOOD); | 217 | return 0; |
221 | return ret; | ||
222 | } | 218 | } |
223 | 219 | ||
224 | int target_scsi2_reservation_reserve(struct se_cmd *cmd) | 220 | sense_reason_t |
221 | target_scsi2_reservation_reserve(struct se_cmd *cmd) | ||
225 | { | 222 | { |
226 | struct se_device *dev = cmd->se_dev; | 223 | struct se_device *dev = cmd->se_dev; |
227 | struct se_session *sess = cmd->se_sess; | 224 | struct se_session *sess = cmd->se_sess; |
228 | struct se_portal_group *tpg; | 225 | struct se_portal_group *tpg; |
229 | int ret = 0, rc; | 226 | sense_reason_t ret = 0; |
227 | int rc; | ||
230 | 228 | ||
231 | if ((cmd->t_task_cdb[1] & 0x01) && | 229 | if ((cmd->t_task_cdb[1] & 0x01) && |
232 | (cmd->t_task_cdb[1] & 0x02)) { | 230 | (cmd->t_task_cdb[1] & 0x02)) { |
233 | pr_err("LongIO and Obselete Bits set, returning" | 231 | pr_err("LongIO and Obselete Bits set, returning" |
234 | " ILLEGAL_REQUEST\n"); | 232 | " ILLEGAL_REQUEST\n"); |
235 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 233 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
236 | ret = -EINVAL; | ||
237 | goto out; | ||
238 | } | 234 | } |
239 | /* | 235 | /* |
240 | * This is currently the case for target_core_mod passthrough struct se_cmd | 236 | * This is currently the case for target_core_mod passthrough struct se_cmd |
@@ -245,13 +241,10 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd) | |||
245 | rc = target_check_scsi2_reservation_conflict(cmd); | 241 | rc = target_check_scsi2_reservation_conflict(cmd); |
246 | if (rc == 1) | 242 | if (rc == 1) |
247 | goto out; | 243 | goto out; |
248 | else if (rc < 0) { | ||
249 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
250 | ret = -EINVAL; | ||
251 | goto out; | ||
252 | } | ||
253 | 244 | ||
254 | ret = 0; | 245 | if (rc < 0) |
246 | return TCM_RESERVATION_CONFLICT; | ||
247 | |||
255 | tpg = sess->se_tpg; | 248 | tpg = sess->se_tpg; |
256 | spin_lock(&dev->dev_reservation_lock); | 249 | spin_lock(&dev->dev_reservation_lock); |
257 | if (dev->dev_reserved_node_acl && | 250 | if (dev->dev_reserved_node_acl && |
@@ -265,8 +258,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd) | |||
265 | " from %s \n", cmd->se_lun->unpacked_lun, | 258 | " from %s \n", cmd->se_lun->unpacked_lun, |
266 | cmd->se_deve->mapped_lun, | 259 | cmd->se_deve->mapped_lun, |
267 | sess->se_node_acl->initiatorname); | 260 | sess->se_node_acl->initiatorname); |
268 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 261 | ret = TCM_RESERVATION_CONFLICT; |
269 | ret = -EINVAL; | ||
270 | goto out_unlock; | 262 | goto out_unlock; |
271 | } | 263 | } |
272 | 264 | ||
@@ -536,7 +528,8 @@ static int core_scsi3_pr_seq_non_holder( | |||
536 | return 1; /* Conflict by default */ | 528 | return 1; /* Conflict by default */ |
537 | } | 529 | } |
538 | 530 | ||
539 | static int target_scsi3_pr_reservation_check(struct se_cmd *cmd) | 531 | static sense_reason_t |
532 | target_scsi3_pr_reservation_check(struct se_cmd *cmd) | ||
540 | { | 533 | { |
541 | struct se_device *dev = cmd->se_dev; | 534 | struct se_device *dev = cmd->se_dev; |
542 | struct se_session *sess = cmd->se_sess; | 535 | struct se_session *sess = cmd->se_sess; |
@@ -562,7 +555,7 @@ static int target_scsi3_pr_reservation_check(struct se_cmd *cmd) | |||
562 | 555 | ||
563 | check_nonholder: | 556 | check_nonholder: |
564 | if (core_scsi3_pr_seq_non_holder(cmd, pr_reg_type)) | 557 | if (core_scsi3_pr_seq_non_holder(cmd, pr_reg_type)) |
565 | return -EBUSY; | 558 | return TCM_RESERVATION_CONFLICT; |
566 | return 0; | 559 | return 0; |
567 | } | 560 | } |
568 | 561 | ||
@@ -1435,7 +1428,8 @@ static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve) | |||
1435 | smp_mb__after_atomic_dec(); | 1428 | smp_mb__after_atomic_dec(); |
1436 | } | 1429 | } |
1437 | 1430 | ||
1438 | static int core_scsi3_decode_spec_i_port( | 1431 | static sense_reason_t |
1432 | core_scsi3_decode_spec_i_port( | ||
1439 | struct se_cmd *cmd, | 1433 | struct se_cmd *cmd, |
1440 | struct se_portal_group *tpg, | 1434 | struct se_portal_group *tpg, |
1441 | unsigned char *l_isid, | 1435 | unsigned char *l_isid, |
@@ -1457,8 +1451,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1457 | unsigned char *buf; | 1451 | unsigned char *buf; |
1458 | unsigned char *ptr, *i_str = NULL, proto_ident, tmp_proto_ident; | 1452 | unsigned char *ptr, *i_str = NULL, proto_ident, tmp_proto_ident; |
1459 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; | 1453 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; |
1454 | sense_reason_t ret; | ||
1460 | u32 tpdl, tid_len = 0; | 1455 | u32 tpdl, tid_len = 0; |
1461 | int ret, dest_local_nexus, prf_isid; | 1456 | int dest_local_nexus, prf_isid; |
1462 | u32 dest_rtpi = 0; | 1457 | u32 dest_rtpi = 0; |
1463 | 1458 | ||
1464 | memset(dest_iport, 0, 64); | 1459 | memset(dest_iport, 0, 64); |
@@ -1473,8 +1468,7 @@ static int core_scsi3_decode_spec_i_port( | |||
1473 | tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); | 1468 | tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); |
1474 | if (!tidh_new) { | 1469 | if (!tidh_new) { |
1475 | pr_err("Unable to allocate tidh_new\n"); | 1470 | pr_err("Unable to allocate tidh_new\n"); |
1476 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1471 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1477 | return -EINVAL; | ||
1478 | } | 1472 | } |
1479 | INIT_LIST_HEAD(&tidh_new->dest_list); | 1473 | INIT_LIST_HEAD(&tidh_new->dest_list); |
1480 | tidh_new->dest_tpg = tpg; | 1474 | tidh_new->dest_tpg = tpg; |
@@ -1486,8 +1480,7 @@ static int core_scsi3_decode_spec_i_port( | |||
1486 | sa_res_key, all_tg_pt, aptpl); | 1480 | sa_res_key, all_tg_pt, aptpl); |
1487 | if (!local_pr_reg) { | 1481 | if (!local_pr_reg) { |
1488 | kfree(tidh_new); | 1482 | kfree(tidh_new); |
1489 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1483 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1490 | return -ENOMEM; | ||
1491 | } | 1484 | } |
1492 | tidh_new->dest_pr_reg = local_pr_reg; | 1485 | tidh_new->dest_pr_reg = local_pr_reg; |
1493 | /* | 1486 | /* |
@@ -1501,12 +1494,16 @@ static int core_scsi3_decode_spec_i_port( | |||
1501 | if (cmd->data_length < 28) { | 1494 | if (cmd->data_length < 28) { |
1502 | pr_warn("SPC-PR: Received PR OUT parameter list" | 1495 | pr_warn("SPC-PR: Received PR OUT parameter list" |
1503 | " length too small: %u\n", cmd->data_length); | 1496 | " length too small: %u\n", cmd->data_length); |
1504 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1497 | ret = TCM_INVALID_PARAMETER_LIST; |
1505 | ret = -EINVAL; | ||
1506 | goto out; | 1498 | goto out; |
1507 | } | 1499 | } |
1508 | 1500 | ||
1509 | buf = transport_kmap_data_sg(cmd); | 1501 | buf = transport_kmap_data_sg(cmd); |
1502 | if (!buf) { | ||
1503 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1504 | goto out; | ||
1505 | } | ||
1506 | |||
1510 | /* | 1507 | /* |
1511 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, | 1508 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, |
1512 | * first extract TransportID Parameter Data Length, and make sure | 1509 | * first extract TransportID Parameter Data Length, and make sure |
@@ -1521,9 +1518,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1521 | pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header" | 1518 | pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header" |
1522 | " does not equal CDB data_length: %u\n", tpdl, | 1519 | " does not equal CDB data_length: %u\n", tpdl, |
1523 | cmd->data_length); | 1520 | cmd->data_length); |
1524 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1521 | ret = TCM_INVALID_PARAMETER_LIST; |
1525 | ret = -EINVAL; | 1522 | goto out_unmap; |
1526 | goto out; | ||
1527 | } | 1523 | } |
1528 | /* | 1524 | /* |
1529 | * Start processing the received transport IDs using the | 1525 | * Start processing the received transport IDs using the |
@@ -1566,16 +1562,13 @@ static int core_scsi3_decode_spec_i_port( | |||
1566 | smp_mb__after_atomic_inc(); | 1562 | smp_mb__after_atomic_inc(); |
1567 | spin_unlock(&dev->se_port_lock); | 1563 | spin_unlock(&dev->se_port_lock); |
1568 | 1564 | ||
1569 | ret = core_scsi3_tpg_depend_item(tmp_tpg); | 1565 | if (core_scsi3_tpg_depend_item(tmp_tpg)) { |
1570 | if (ret != 0) { | ||
1571 | pr_err(" core_scsi3_tpg_depend_item()" | 1566 | pr_err(" core_scsi3_tpg_depend_item()" |
1572 | " for tmp_tpg\n"); | 1567 | " for tmp_tpg\n"); |
1573 | atomic_dec(&tmp_tpg->tpg_pr_ref_count); | 1568 | atomic_dec(&tmp_tpg->tpg_pr_ref_count); |
1574 | smp_mb__after_atomic_dec(); | 1569 | smp_mb__after_atomic_dec(); |
1575 | cmd->scsi_sense_reason = | 1570 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1576 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1571 | goto out_unmap; |
1577 | ret = -EINVAL; | ||
1578 | goto out; | ||
1579 | } | 1572 | } |
1580 | /* | 1573 | /* |
1581 | * Locate the destination initiator ACL to be registered | 1574 | * Locate the destination initiator ACL to be registered |
@@ -1597,17 +1590,14 @@ static int core_scsi3_decode_spec_i_port( | |||
1597 | continue; | 1590 | continue; |
1598 | } | 1591 | } |
1599 | 1592 | ||
1600 | ret = core_scsi3_nodeacl_depend_item(dest_node_acl); | 1593 | if (core_scsi3_nodeacl_depend_item(dest_node_acl)) { |
1601 | if (ret != 0) { | ||
1602 | pr_err("configfs_depend_item() failed" | 1594 | pr_err("configfs_depend_item() failed" |
1603 | " for dest_node_acl->acl_group\n"); | 1595 | " for dest_node_acl->acl_group\n"); |
1604 | atomic_dec(&dest_node_acl->acl_pr_ref_count); | 1596 | atomic_dec(&dest_node_acl->acl_pr_ref_count); |
1605 | smp_mb__after_atomic_dec(); | 1597 | smp_mb__after_atomic_dec(); |
1606 | core_scsi3_tpg_undepend_item(tmp_tpg); | 1598 | core_scsi3_tpg_undepend_item(tmp_tpg); |
1607 | cmd->scsi_sense_reason = | 1599 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1608 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1600 | goto out_unmap; |
1609 | ret = -EINVAL; | ||
1610 | goto out; | ||
1611 | } | 1601 | } |
1612 | 1602 | ||
1613 | dest_tpg = tmp_tpg; | 1603 | dest_tpg = tmp_tpg; |
@@ -1624,9 +1614,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1624 | if (!dest_tpg) { | 1614 | if (!dest_tpg) { |
1625 | pr_err("SPC-3 PR SPEC_I_PT: Unable to locate" | 1615 | pr_err("SPC-3 PR SPEC_I_PT: Unable to locate" |
1626 | " dest_tpg\n"); | 1616 | " dest_tpg\n"); |
1627 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1617 | ret = TCM_INVALID_PARAMETER_LIST; |
1628 | ret = -EINVAL; | 1618 | goto out_unmap; |
1629 | goto out; | ||
1630 | } | 1619 | } |
1631 | 1620 | ||
1632 | pr_debug("SPC-3 PR SPEC_I_PT: Got %s data_length: %u tpdl: %u" | 1621 | pr_debug("SPC-3 PR SPEC_I_PT: Got %s data_length: %u tpdl: %u" |
@@ -1639,9 +1628,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1639 | " %u for Transport ID: %s\n", tid_len, ptr); | 1628 | " %u for Transport ID: %s\n", tid_len, ptr); |
1640 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1629 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1641 | core_scsi3_tpg_undepend_item(dest_tpg); | 1630 | core_scsi3_tpg_undepend_item(dest_tpg); |
1642 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1631 | ret = TCM_INVALID_PARAMETER_LIST; |
1643 | ret = -EINVAL; | 1632 | goto out_unmap; |
1644 | goto out; | ||
1645 | } | 1633 | } |
1646 | /* | 1634 | /* |
1647 | * Locate the desintation struct se_dev_entry pointer for matching | 1635 | * Locate the desintation struct se_dev_entry pointer for matching |
@@ -1658,23 +1646,19 @@ static int core_scsi3_decode_spec_i_port( | |||
1658 | 1646 | ||
1659 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1647 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1660 | core_scsi3_tpg_undepend_item(dest_tpg); | 1648 | core_scsi3_tpg_undepend_item(dest_tpg); |
1661 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1649 | ret = TCM_INVALID_PARAMETER_LIST; |
1662 | ret = -EINVAL; | 1650 | goto out_unmap; |
1663 | goto out; | ||
1664 | } | 1651 | } |
1665 | 1652 | ||
1666 | ret = core_scsi3_lunacl_depend_item(dest_se_deve); | 1653 | if (core_scsi3_lunacl_depend_item(dest_se_deve)) { |
1667 | if (ret < 0) { | ||
1668 | pr_err("core_scsi3_lunacl_depend_item()" | 1654 | pr_err("core_scsi3_lunacl_depend_item()" |
1669 | " failed\n"); | 1655 | " failed\n"); |
1670 | atomic_dec(&dest_se_deve->pr_ref_count); | 1656 | atomic_dec(&dest_se_deve->pr_ref_count); |
1671 | smp_mb__after_atomic_dec(); | 1657 | smp_mb__after_atomic_dec(); |
1672 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1658 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1673 | core_scsi3_tpg_undepend_item(dest_tpg); | 1659 | core_scsi3_tpg_undepend_item(dest_tpg); |
1674 | cmd->scsi_sense_reason = | 1660 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1675 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1661 | goto out_unmap; |
1676 | ret = -EINVAL; | ||
1677 | goto out; | ||
1678 | } | 1662 | } |
1679 | 1663 | ||
1680 | pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node: %s" | 1664 | pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node: %s" |
@@ -1710,10 +1694,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1710 | core_scsi3_lunacl_undepend_item(dest_se_deve); | 1694 | core_scsi3_lunacl_undepend_item(dest_se_deve); |
1711 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1695 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1712 | core_scsi3_tpg_undepend_item(dest_tpg); | 1696 | core_scsi3_tpg_undepend_item(dest_tpg); |
1713 | cmd->scsi_sense_reason = | 1697 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1714 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1698 | goto out_unmap; |
1715 | ret = -ENOMEM; | ||
1716 | goto out; | ||
1717 | } | 1699 | } |
1718 | INIT_LIST_HEAD(&tidh_new->dest_list); | 1700 | INIT_LIST_HEAD(&tidh_new->dest_list); |
1719 | tidh_new->dest_tpg = dest_tpg; | 1701 | tidh_new->dest_tpg = dest_tpg; |
@@ -1744,9 +1726,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1744 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1726 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1745 | core_scsi3_tpg_undepend_item(dest_tpg); | 1727 | core_scsi3_tpg_undepend_item(dest_tpg); |
1746 | kfree(tidh_new); | 1728 | kfree(tidh_new); |
1747 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1729 | ret = TCM_INVALID_PARAMETER_LIST; |
1748 | ret = -EINVAL; | 1730 | goto out_unmap; |
1749 | goto out; | ||
1750 | } | 1731 | } |
1751 | tidh_new->dest_pr_reg = dest_pr_reg; | 1732 | tidh_new->dest_pr_reg = dest_pr_reg; |
1752 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); | 1733 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); |
@@ -1804,8 +1785,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1804 | } | 1785 | } |
1805 | 1786 | ||
1806 | return 0; | 1787 | return 0; |
1807 | out: | 1788 | out_unmap: |
1808 | transport_kunmap_data_sg(cmd); | 1789 | transport_kunmap_data_sg(cmd); |
1790 | out: | ||
1809 | /* | 1791 | /* |
1810 | * For the failure case, release everything from tid_dest_list | 1792 | * For the failure case, release everything from tid_dest_list |
1811 | * including *dest_pr_reg and the configfs dependances.. | 1793 | * including *dest_pr_reg and the configfs dependances.. |
@@ -2020,14 +2002,15 @@ static int __core_scsi3_write_aptpl_to_file( | |||
2020 | return 0; | 2002 | return 0; |
2021 | } | 2003 | } |
2022 | 2004 | ||
2023 | static int core_scsi3_update_and_write_aptpl( | 2005 | static int |
2024 | struct se_device *dev, | 2006 | core_scsi3_update_and_write_aptpl(struct se_device *dev, unsigned char *in_buf, |
2025 | unsigned char *in_buf, | 2007 | u32 in_pr_aptpl_buf_len) |
2026 | u32 in_pr_aptpl_buf_len) | ||
2027 | { | 2008 | { |
2028 | unsigned char null_buf[64], *buf; | 2009 | unsigned char null_buf[64], *buf; |
2029 | u32 pr_aptpl_buf_len; | 2010 | u32 pr_aptpl_buf_len; |
2030 | int ret, clear_aptpl_metadata = 0; | 2011 | int clear_aptpl_metadata = 0; |
2012 | int ret; | ||
2013 | |||
2031 | /* | 2014 | /* |
2032 | * Can be called with a NULL pointer from PROUT service action CLEAR | 2015 | * Can be called with a NULL pointer from PROUT service action CLEAR |
2033 | */ | 2016 | */ |
@@ -2049,25 +2032,17 @@ static int core_scsi3_update_and_write_aptpl( | |||
2049 | clear_aptpl_metadata); | 2032 | clear_aptpl_metadata); |
2050 | if (ret != 0) | 2033 | if (ret != 0) |
2051 | return ret; | 2034 | return ret; |
2035 | |||
2052 | /* | 2036 | /* |
2053 | * __core_scsi3_write_aptpl_to_file() will call strlen() | 2037 | * __core_scsi3_write_aptpl_to_file() will call strlen() |
2054 | * on the passed buf to determine pr_aptpl_buf_len. | 2038 | * on the passed buf to determine pr_aptpl_buf_len. |
2055 | */ | 2039 | */ |
2056 | ret = __core_scsi3_write_aptpl_to_file(dev, buf, 0); | 2040 | return __core_scsi3_write_aptpl_to_file(dev, buf, 0); |
2057 | if (ret != 0) | ||
2058 | return ret; | ||
2059 | |||
2060 | return ret; | ||
2061 | } | 2041 | } |
2062 | 2042 | ||
2063 | static int core_scsi3_emulate_pro_register( | 2043 | static sense_reason_t |
2064 | struct se_cmd *cmd, | 2044 | core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, |
2065 | u64 res_key, | 2045 | int aptpl, int all_tg_pt, int spec_i_pt, int ignore_key) |
2066 | u64 sa_res_key, | ||
2067 | int aptpl, | ||
2068 | int all_tg_pt, | ||
2069 | int spec_i_pt, | ||
2070 | int ignore_key) | ||
2071 | { | 2046 | { |
2072 | struct se_session *se_sess = cmd->se_sess; | 2047 | struct se_session *se_sess = cmd->se_sess; |
2073 | struct se_device *dev = cmd->se_dev; | 2048 | struct se_device *dev = cmd->se_dev; |
@@ -2079,12 +2054,12 @@ static int core_scsi3_emulate_pro_register( | |||
2079 | /* Used for APTPL metadata w/ UNREGISTER */ | 2054 | /* Used for APTPL metadata w/ UNREGISTER */ |
2080 | unsigned char *pr_aptpl_buf = NULL; | 2055 | unsigned char *pr_aptpl_buf = NULL; |
2081 | unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL; | 2056 | unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL; |
2082 | int pr_holder = 0, ret = 0, type; | 2057 | sense_reason_t ret; |
2058 | int pr_holder = 0, type; | ||
2083 | 2059 | ||
2084 | if (!se_sess || !se_lun) { | 2060 | if (!se_sess || !se_lun) { |
2085 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2061 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2086 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2062 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2087 | return -EINVAL; | ||
2088 | } | 2063 | } |
2089 | se_tpg = se_sess->se_tpg; | 2064 | se_tpg = se_sess->se_tpg; |
2090 | se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; | 2065 | se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; |
@@ -2103,8 +2078,7 @@ static int core_scsi3_emulate_pro_register( | |||
2103 | if (res_key) { | 2078 | if (res_key) { |
2104 | pr_warn("SPC-3 PR: Reservation Key non-zero" | 2079 | pr_warn("SPC-3 PR: Reservation Key non-zero" |
2105 | " for SA REGISTER, returning CONFLICT\n"); | 2080 | " for SA REGISTER, returning CONFLICT\n"); |
2106 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2081 | return TCM_RESERVATION_CONFLICT; |
2107 | return -EINVAL; | ||
2108 | } | 2082 | } |
2109 | /* | 2083 | /* |
2110 | * Do nothing but return GOOD status. | 2084 | * Do nothing but return GOOD status. |
@@ -2118,15 +2092,13 @@ static int core_scsi3_emulate_pro_register( | |||
2118 | * Port Endpoint that the PRO was received from on the | 2092 | * Port Endpoint that the PRO was received from on the |
2119 | * Logical Unit of the SCSI device server. | 2093 | * Logical Unit of the SCSI device server. |
2120 | */ | 2094 | */ |
2121 | ret = core_scsi3_alloc_registration(cmd->se_dev, | 2095 | if (core_scsi3_alloc_registration(cmd->se_dev, |
2122 | se_sess->se_node_acl, se_deve, isid_ptr, | 2096 | se_sess->se_node_acl, se_deve, isid_ptr, |
2123 | sa_res_key, all_tg_pt, aptpl, | 2097 | sa_res_key, all_tg_pt, aptpl, |
2124 | ignore_key, 0); | 2098 | ignore_key, 0)) { |
2125 | if (ret != 0) { | ||
2126 | pr_err("Unable to allocate" | 2099 | pr_err("Unable to allocate" |
2127 | " struct t10_pr_registration\n"); | 2100 | " struct t10_pr_registration\n"); |
2128 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 2101 | return TCM_INVALID_PARAMETER_LIST; |
2129 | return -EINVAL; | ||
2130 | } | 2102 | } |
2131 | } else { | 2103 | } else { |
2132 | /* | 2104 | /* |
@@ -2160,201 +2132,192 @@ static int core_scsi3_emulate_pro_register( | |||
2160 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, | 2132 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, |
2161 | se_sess->se_node_acl, se_sess); | 2133 | se_sess->se_node_acl, se_sess); |
2162 | 2134 | ||
2163 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 2135 | if (core_scsi3_update_and_write_aptpl(cmd->se_dev, |
2164 | &pr_reg->pr_aptpl_buf[0], | 2136 | &pr_reg->pr_aptpl_buf[0], |
2165 | pr_tmpl->pr_aptpl_buf_len); | 2137 | pr_tmpl->pr_aptpl_buf_len)) { |
2166 | if (!ret) { | ||
2167 | pr_tmpl->pr_aptpl_active = 1; | 2138 | pr_tmpl->pr_aptpl_active = 1; |
2168 | pr_debug("SPC-3 PR: Set APTPL Bit Activated for REGISTER\n"); | 2139 | pr_debug("SPC-3 PR: Set APTPL Bit Activated for REGISTER\n"); |
2169 | } | 2140 | } |
2170 | 2141 | ||
2171 | core_scsi3_put_pr_reg(pr_reg); | 2142 | goto out_put_pr_reg; |
2172 | return ret; | 2143 | } |
2173 | } else { | 2144 | |
2174 | /* | 2145 | /* |
2175 | * Locate the existing *pr_reg via struct se_node_acl pointers | 2146 | * Locate the existing *pr_reg via struct se_node_acl pointers |
2176 | */ | 2147 | */ |
2177 | pr_reg = pr_reg_e; | 2148 | pr_reg = pr_reg_e; |
2178 | type = pr_reg->pr_res_type; | 2149 | type = pr_reg->pr_res_type; |
2179 | 2150 | ||
2180 | if (!ignore_key) { | 2151 | if (!ignore_key) { |
2181 | if (res_key != pr_reg->pr_res_key) { | 2152 | if (res_key != pr_reg->pr_res_key) { |
2182 | pr_err("SPC-3 PR REGISTER: Received" | 2153 | pr_err("SPC-3 PR REGISTER: Received" |
2183 | " res_key: 0x%016Lx does not match" | 2154 | " res_key: 0x%016Lx does not match" |
2184 | " existing SA REGISTER res_key:" | 2155 | " existing SA REGISTER res_key:" |
2185 | " 0x%016Lx\n", res_key, | 2156 | " 0x%016Lx\n", res_key, |
2186 | pr_reg->pr_res_key); | 2157 | pr_reg->pr_res_key); |
2187 | core_scsi3_put_pr_reg(pr_reg); | 2158 | ret = TCM_RESERVATION_CONFLICT; |
2188 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2159 | goto out_put_pr_reg; |
2189 | return -EINVAL; | ||
2190 | } | ||
2191 | } | 2160 | } |
2192 | if (spec_i_pt) { | 2161 | } |
2193 | pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" | 2162 | |
2194 | " set while sa_res_key=0\n"); | 2163 | if (spec_i_pt) { |
2195 | core_scsi3_put_pr_reg(pr_reg); | 2164 | pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" |
2196 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 2165 | " set while sa_res_key=0\n"); |
2197 | return -EINVAL; | 2166 | ret = TCM_INVALID_PARAMETER_LIST; |
2167 | goto out_put_pr_reg; | ||
2168 | } | ||
2169 | |||
2170 | /* | ||
2171 | * An existing ALL_TG_PT=1 registration being released | ||
2172 | * must also set ALL_TG_PT=1 in the incoming PROUT. | ||
2173 | */ | ||
2174 | if (pr_reg->pr_reg_all_tg_pt && !(all_tg_pt)) { | ||
2175 | pr_err("SPC-3 PR UNREGISTER: ALL_TG_PT=1" | ||
2176 | " registration exists, but ALL_TG_PT=1 bit not" | ||
2177 | " present in received PROUT\n"); | ||
2178 | ret = TCM_INVALID_CDB_FIELD; | ||
2179 | goto out_put_pr_reg; | ||
2180 | } | ||
2181 | |||
2182 | /* | ||
2183 | * Allocate APTPL metadata buffer used for UNREGISTER ops | ||
2184 | */ | ||
2185 | if (aptpl) { | ||
2186 | pr_aptpl_buf = kzalloc(pr_tmpl->pr_aptpl_buf_len, | ||
2187 | GFP_KERNEL); | ||
2188 | if (!pr_aptpl_buf) { | ||
2189 | pr_err("Unable to allocate" | ||
2190 | " pr_aptpl_buf\n"); | ||
2191 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2192 | goto out_put_pr_reg; | ||
2198 | } | 2193 | } |
2199 | /* | 2194 | } |
2200 | * An existing ALL_TG_PT=1 registration being released | 2195 | |
2201 | * must also set ALL_TG_PT=1 in the incoming PROUT. | 2196 | /* |
2202 | */ | 2197 | * sa_res_key=0 Unregister Reservation Key for registered I_T |
2203 | if (pr_reg->pr_reg_all_tg_pt && !(all_tg_pt)) { | 2198 | * Nexus sa_res_key=1 Change Reservation Key for registered I_T |
2204 | pr_err("SPC-3 PR UNREGISTER: ALL_TG_PT=1" | 2199 | * Nexus. |
2205 | " registration exists, but ALL_TG_PT=1 bit not" | 2200 | */ |
2206 | " present in received PROUT\n"); | 2201 | if (!sa_res_key) { |
2207 | core_scsi3_put_pr_reg(pr_reg); | 2202 | pr_holder = core_scsi3_check_implict_release( |
2208 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 2203 | cmd->se_dev, pr_reg); |
2209 | return -EINVAL; | 2204 | if (pr_holder < 0) { |
2205 | kfree(pr_aptpl_buf); | ||
2206 | ret = TCM_RESERVATION_CONFLICT; | ||
2207 | goto out_put_pr_reg; | ||
2210 | } | 2208 | } |
2209 | |||
2210 | spin_lock(&pr_tmpl->registration_lock); | ||
2211 | /* | 2211 | /* |
2212 | * Allocate APTPL metadata buffer used for UNREGISTER ops | 2212 | * Release all ALL_TG_PT=1 for the matching SCSI Initiator Port |
2213 | * and matching pr_res_key. | ||
2213 | */ | 2214 | */ |
2214 | if (aptpl) { | 2215 | if (pr_reg->pr_reg_all_tg_pt) { |
2215 | pr_aptpl_buf = kzalloc(pr_tmpl->pr_aptpl_buf_len, | 2216 | list_for_each_entry_safe(pr_reg_p, pr_reg_tmp, |
2216 | GFP_KERNEL); | 2217 | &pr_tmpl->registration_list, |
2217 | if (!pr_aptpl_buf) { | 2218 | pr_reg_list) { |
2218 | pr_err("Unable to allocate" | 2219 | |
2219 | " pr_aptpl_buf\n"); | 2220 | if (!pr_reg_p->pr_reg_all_tg_pt) |
2220 | core_scsi3_put_pr_reg(pr_reg); | 2221 | continue; |
2221 | cmd->scsi_sense_reason = | 2222 | if (pr_reg_p->pr_res_key != res_key) |
2222 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2223 | continue; |
2223 | return -EINVAL; | 2224 | if (pr_reg == pr_reg_p) |
2225 | continue; | ||
2226 | if (strcmp(pr_reg->pr_reg_nacl->initiatorname, | ||
2227 | pr_reg_p->pr_reg_nacl->initiatorname)) | ||
2228 | continue; | ||
2229 | |||
2230 | __core_scsi3_free_registration(dev, | ||
2231 | pr_reg_p, NULL, 0); | ||
2224 | } | 2232 | } |
2225 | } | 2233 | } |
2234 | |||
2226 | /* | 2235 | /* |
2227 | * sa_res_key=0 Unregister Reservation Key for registered I_T | 2236 | * Release the calling I_T Nexus registration now.. |
2228 | * Nexus sa_res_key=1 Change Reservation Key for registered I_T | ||
2229 | * Nexus. | ||
2230 | */ | 2237 | */ |
2231 | if (!sa_res_key) { | 2238 | __core_scsi3_free_registration(cmd->se_dev, pr_reg, NULL, 1); |
2232 | pr_holder = core_scsi3_check_implict_release( | ||
2233 | cmd->se_dev, pr_reg); | ||
2234 | if (pr_holder < 0) { | ||
2235 | kfree(pr_aptpl_buf); | ||
2236 | core_scsi3_put_pr_reg(pr_reg); | ||
2237 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
2238 | return -EINVAL; | ||
2239 | } | ||
2240 | |||
2241 | spin_lock(&pr_tmpl->registration_lock); | ||
2242 | /* | ||
2243 | * Release all ALL_TG_PT=1 for the matching SCSI Initiator Port | ||
2244 | * and matching pr_res_key. | ||
2245 | */ | ||
2246 | if (pr_reg->pr_reg_all_tg_pt) { | ||
2247 | list_for_each_entry_safe(pr_reg_p, pr_reg_tmp, | ||
2248 | &pr_tmpl->registration_list, | ||
2249 | pr_reg_list) { | ||
2250 | |||
2251 | if (!pr_reg_p->pr_reg_all_tg_pt) | ||
2252 | continue; | ||
2253 | 2239 | ||
2254 | if (pr_reg_p->pr_res_key != res_key) | 2240 | /* |
2255 | continue; | 2241 | * From spc4r17, section 5.7.11.3 Unregistering |
2256 | 2242 | * | |
2257 | if (pr_reg == pr_reg_p) | 2243 | * If the persistent reservation is a registrants only |
2258 | continue; | 2244 | * type, the device server shall establish a unit |
2259 | 2245 | * attention condition for the initiator port associated | |
2260 | if (strcmp(pr_reg->pr_reg_nacl->initiatorname, | 2246 | * with every registered I_T nexus except for the I_T |
2261 | pr_reg_p->pr_reg_nacl->initiatorname)) | 2247 | * nexus on which the PERSISTENT RESERVE OUT command was |
2262 | continue; | 2248 | * received, with the additional sense code set to |
2263 | 2249 | * RESERVATIONS RELEASED. | |
2264 | __core_scsi3_free_registration(dev, | 2250 | */ |
2265 | pr_reg_p, NULL, 0); | 2251 | if (pr_holder && |
2266 | } | 2252 | (type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY || |
2267 | } | 2253 | type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY)) { |
2268 | /* | 2254 | list_for_each_entry(pr_reg_p, |
2269 | * Release the calling I_T Nexus registration now.. | 2255 | &pr_tmpl->registration_list, |
2270 | */ | 2256 | pr_reg_list) { |
2271 | __core_scsi3_free_registration(cmd->se_dev, pr_reg, | 2257 | |
2272 | NULL, 1); | 2258 | core_scsi3_ua_allocate( |
2273 | /* | 2259 | pr_reg_p->pr_reg_nacl, |
2274 | * From spc4r17, section 5.7.11.3 Unregistering | 2260 | pr_reg_p->pr_res_mapped_lun, |
2275 | * | 2261 | 0x2A, |
2276 | * If the persistent reservation is a registrants only | 2262 | ASCQ_2AH_RESERVATIONS_RELEASED); |
2277 | * type, the device server shall establish a unit | ||
2278 | * attention condition for the initiator port associated | ||
2279 | * with every registered I_T nexus except for the I_T | ||
2280 | * nexus on which the PERSISTENT RESERVE OUT command was | ||
2281 | * received, with the additional sense code set to | ||
2282 | * RESERVATIONS RELEASED. | ||
2283 | */ | ||
2284 | if (pr_holder && | ||
2285 | ((type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) || | ||
2286 | (type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY))) { | ||
2287 | list_for_each_entry(pr_reg_p, | ||
2288 | &pr_tmpl->registration_list, | ||
2289 | pr_reg_list) { | ||
2290 | |||
2291 | core_scsi3_ua_allocate( | ||
2292 | pr_reg_p->pr_reg_nacl, | ||
2293 | pr_reg_p->pr_res_mapped_lun, | ||
2294 | 0x2A, | ||
2295 | ASCQ_2AH_RESERVATIONS_RELEASED); | ||
2296 | } | ||
2297 | } | 2263 | } |
2298 | spin_unlock(&pr_tmpl->registration_lock); | 2264 | } |
2265 | spin_unlock(&pr_tmpl->registration_lock); | ||
2299 | 2266 | ||
2300 | if (!aptpl) { | 2267 | if (!aptpl) { |
2301 | pr_tmpl->pr_aptpl_active = 0; | 2268 | pr_tmpl->pr_aptpl_active = 0; |
2302 | core_scsi3_update_and_write_aptpl(dev, NULL, 0); | 2269 | core_scsi3_update_and_write_aptpl(dev, NULL, 0); |
2303 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated" | 2270 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated" |
2304 | " for UNREGISTER\n"); | 2271 | " for UNREGISTER\n"); |
2305 | return 0; | 2272 | return 0; |
2306 | } | 2273 | } |
2307 | 2274 | ||
2308 | ret = core_scsi3_update_and_write_aptpl(dev, | 2275 | if (!core_scsi3_update_and_write_aptpl(dev, &pr_aptpl_buf[0], |
2309 | &pr_aptpl_buf[0], | 2276 | pr_tmpl->pr_aptpl_buf_len)) { |
2310 | pr_tmpl->pr_aptpl_buf_len); | 2277 | pr_tmpl->pr_aptpl_active = 1; |
2311 | if (!ret) { | 2278 | pr_debug("SPC-3 PR: Set APTPL Bit Activated" |
2312 | pr_tmpl->pr_aptpl_active = 1; | 2279 | " for UNREGISTER\n"); |
2313 | pr_debug("SPC-3 PR: Set APTPL Bit Activated" | 2280 | } |
2314 | " for UNREGISTER\n"); | ||
2315 | } | ||
2316 | 2281 | ||
2317 | kfree(pr_aptpl_buf); | 2282 | goto out_free_aptpl_buf; |
2318 | return ret; | 2283 | } |
2319 | } else { | ||
2320 | /* | ||
2321 | * Increment PRgeneration counter for struct se_device" | ||
2322 | * upon a successful REGISTER, see spc4r17 section 6.3.2 | ||
2323 | * READ_KEYS service action. | ||
2324 | */ | ||
2325 | pr_reg->pr_res_generation = core_scsi3_pr_generation( | ||
2326 | cmd->se_dev); | ||
2327 | pr_reg->pr_res_key = sa_res_key; | ||
2328 | pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation" | ||
2329 | " Key for %s to: 0x%016Lx PRgeneration:" | ||
2330 | " 0x%08x\n", cmd->se_tfo->get_fabric_name(), | ||
2331 | (ignore_key) ? "_AND_IGNORE_EXISTING_KEY" : "", | ||
2332 | pr_reg->pr_reg_nacl->initiatorname, | ||
2333 | pr_reg->pr_res_key, pr_reg->pr_res_generation); | ||
2334 | |||
2335 | if (!aptpl) { | ||
2336 | pr_tmpl->pr_aptpl_active = 0; | ||
2337 | core_scsi3_update_and_write_aptpl(dev, NULL, 0); | ||
2338 | core_scsi3_put_pr_reg(pr_reg); | ||
2339 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated" | ||
2340 | " for REGISTER\n"); | ||
2341 | return 0; | ||
2342 | } | ||
2343 | 2284 | ||
2344 | ret = core_scsi3_update_and_write_aptpl(dev, | 2285 | /* |
2345 | &pr_aptpl_buf[0], | 2286 | * Increment PRgeneration counter for struct se_device" |
2346 | pr_tmpl->pr_aptpl_buf_len); | 2287 | * upon a successful REGISTER, see spc4r17 section 6.3.2 |
2347 | if (!ret) { | 2288 | * READ_KEYS service action. |
2348 | pr_tmpl->pr_aptpl_active = 1; | 2289 | */ |
2349 | pr_debug("SPC-3 PR: Set APTPL Bit Activated" | 2290 | pr_reg->pr_res_generation = core_scsi3_pr_generation(cmd->se_dev); |
2350 | " for REGISTER\n"); | 2291 | pr_reg->pr_res_key = sa_res_key; |
2351 | } | 2292 | pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation" |
2293 | " Key for %s to: 0x%016Lx PRgeneration:" | ||
2294 | " 0x%08x\n", cmd->se_tfo->get_fabric_name(), | ||
2295 | (ignore_key) ? "_AND_IGNORE_EXISTING_KEY" : "", | ||
2296 | pr_reg->pr_reg_nacl->initiatorname, | ||
2297 | pr_reg->pr_res_key, pr_reg->pr_res_generation); | ||
2352 | 2298 | ||
2353 | kfree(pr_aptpl_buf); | 2299 | if (!aptpl) { |
2354 | core_scsi3_put_pr_reg(pr_reg); | 2300 | pr_tmpl->pr_aptpl_active = 0; |
2355 | } | 2301 | core_scsi3_update_and_write_aptpl(dev, NULL, 0); |
2302 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated" | ||
2303 | " for REGISTER\n"); | ||
2304 | ret = 0; | ||
2305 | goto out_put_pr_reg; | ||
2356 | } | 2306 | } |
2357 | return 0; | 2307 | |
2308 | if (!core_scsi3_update_and_write_aptpl(dev, &pr_aptpl_buf[0], | ||
2309 | pr_tmpl->pr_aptpl_buf_len)) { | ||
2310 | pr_tmpl->pr_aptpl_active = 1; | ||
2311 | pr_debug("SPC-3 PR: Set APTPL Bit Activated" | ||
2312 | " for REGISTER\n"); | ||
2313 | } | ||
2314 | |||
2315 | out_free_aptpl_buf: | ||
2316 | kfree(pr_aptpl_buf); | ||
2317 | ret = 0; | ||
2318 | out_put_pr_reg: | ||
2319 | core_scsi3_put_pr_reg(pr_reg); | ||
2320 | return ret; | ||
2358 | } | 2321 | } |
2359 | 2322 | ||
2360 | unsigned char *core_scsi3_pr_dump_type(int type) | 2323 | unsigned char *core_scsi3_pr_dump_type(int type) |
@@ -2379,26 +2342,23 @@ unsigned char *core_scsi3_pr_dump_type(int type) | |||
2379 | return "Unknown SPC-3 PR Type"; | 2342 | return "Unknown SPC-3 PR Type"; |
2380 | } | 2343 | } |
2381 | 2344 | ||
2382 | static int core_scsi3_pro_reserve( | 2345 | static sense_reason_t |
2383 | struct se_cmd *cmd, | 2346 | core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) |
2384 | struct se_device *dev, | ||
2385 | int type, | ||
2386 | int scope, | ||
2387 | u64 res_key) | ||
2388 | { | 2347 | { |
2348 | struct se_device *dev = cmd->se_dev; | ||
2389 | struct se_session *se_sess = cmd->se_sess; | 2349 | struct se_session *se_sess = cmd->se_sess; |
2390 | struct se_lun *se_lun = cmd->se_lun; | 2350 | struct se_lun *se_lun = cmd->se_lun; |
2391 | struct t10_pr_registration *pr_reg, *pr_res_holder; | 2351 | struct t10_pr_registration *pr_reg, *pr_res_holder; |
2392 | struct t10_reservation *pr_tmpl = &dev->t10_pr; | 2352 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2393 | char i_buf[PR_REG_ISID_ID_LEN]; | 2353 | char i_buf[PR_REG_ISID_ID_LEN]; |
2394 | int ret, prf_isid; | 2354 | sense_reason_t ret; |
2355 | int prf_isid; | ||
2395 | 2356 | ||
2396 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 2357 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
2397 | 2358 | ||
2398 | if (!se_sess || !se_lun) { | 2359 | if (!se_sess || !se_lun) { |
2399 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2360 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2400 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2361 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2401 | return -EINVAL; | ||
2402 | } | 2362 | } |
2403 | /* | 2363 | /* |
2404 | * Locate the existing *pr_reg via struct se_node_acl pointers | 2364 | * Locate the existing *pr_reg via struct se_node_acl pointers |
@@ -2408,8 +2368,7 @@ static int core_scsi3_pro_reserve( | |||
2408 | if (!pr_reg) { | 2368 | if (!pr_reg) { |
2409 | pr_err("SPC-3 PR: Unable to locate" | 2369 | pr_err("SPC-3 PR: Unable to locate" |
2410 | " PR_REGISTERED *pr_reg for RESERVE\n"); | 2370 | " PR_REGISTERED *pr_reg for RESERVE\n"); |
2411 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2371 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2412 | return -EINVAL; | ||
2413 | } | 2372 | } |
2414 | /* | 2373 | /* |
2415 | * From spc4r17 Section 5.7.9: Reserving: | 2374 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2424,9 +2383,8 @@ static int core_scsi3_pro_reserve( | |||
2424 | pr_err("SPC-3 PR RESERVE: Received res_key: 0x%016Lx" | 2383 | pr_err("SPC-3 PR RESERVE: Received res_key: 0x%016Lx" |
2425 | " does not match existing SA REGISTER res_key:" | 2384 | " does not match existing SA REGISTER res_key:" |
2426 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 2385 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
2427 | core_scsi3_put_pr_reg(pr_reg); | 2386 | ret = TCM_RESERVATION_CONFLICT; |
2428 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2387 | goto out_put_pr_reg; |
2429 | return -EINVAL; | ||
2430 | } | 2388 | } |
2431 | /* | 2389 | /* |
2432 | * From spc4r17 Section 5.7.9: Reserving: | 2390 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2440,9 +2398,8 @@ static int core_scsi3_pro_reserve( | |||
2440 | */ | 2398 | */ |
2441 | if (scope != PR_SCOPE_LU_SCOPE) { | 2399 | if (scope != PR_SCOPE_LU_SCOPE) { |
2442 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); | 2400 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); |
2443 | core_scsi3_put_pr_reg(pr_reg); | 2401 | ret = TCM_INVALID_PARAMETER_LIST; |
2444 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 2402 | goto out_put_pr_reg; |
2445 | return -EINVAL; | ||
2446 | } | 2403 | } |
2447 | /* | 2404 | /* |
2448 | * See if we have an existing PR reservation holder pointer at | 2405 | * See if we have an existing PR reservation holder pointer at |
@@ -2473,9 +2430,8 @@ static int core_scsi3_pro_reserve( | |||
2473 | pr_res_holder->pr_reg_nacl->initiatorname); | 2430 | pr_res_holder->pr_reg_nacl->initiatorname); |
2474 | 2431 | ||
2475 | spin_unlock(&dev->dev_reservation_lock); | 2432 | spin_unlock(&dev->dev_reservation_lock); |
2476 | core_scsi3_put_pr_reg(pr_reg); | 2433 | ret = TCM_RESERVATION_CONFLICT; |
2477 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2434 | goto out_put_pr_reg; |
2478 | return -EINVAL; | ||
2479 | } | 2435 | } |
2480 | /* | 2436 | /* |
2481 | * From spc4r17 Section 5.7.9: Reserving: | 2437 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2497,9 +2453,8 @@ static int core_scsi3_pro_reserve( | |||
2497 | pr_res_holder->pr_reg_nacl->initiatorname); | 2453 | pr_res_holder->pr_reg_nacl->initiatorname); |
2498 | 2454 | ||
2499 | spin_unlock(&dev->dev_reservation_lock); | 2455 | spin_unlock(&dev->dev_reservation_lock); |
2500 | core_scsi3_put_pr_reg(pr_reg); | 2456 | ret = TCM_RESERVATION_CONFLICT; |
2501 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2457 | goto out_put_pr_reg; |
2502 | return -EINVAL; | ||
2503 | } | 2458 | } |
2504 | /* | 2459 | /* |
2505 | * From spc4r17 Section 5.7.9: Reserving: | 2460 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2512,8 +2467,8 @@ static int core_scsi3_pro_reserve( | |||
2512 | * shall completethe command with GOOD status. | 2467 | * shall completethe command with GOOD status. |
2513 | */ | 2468 | */ |
2514 | spin_unlock(&dev->dev_reservation_lock); | 2469 | spin_unlock(&dev->dev_reservation_lock); |
2515 | core_scsi3_put_pr_reg(pr_reg); | 2470 | ret = 0; |
2516 | return 0; | 2471 | goto out_put_pr_reg; |
2517 | } | 2472 | } |
2518 | /* | 2473 | /* |
2519 | * Otherwise, our *pr_reg becomes the PR reservation holder for said | 2474 | * Otherwise, our *pr_reg becomes the PR reservation holder for said |
@@ -2537,27 +2492,24 @@ static int core_scsi3_pro_reserve( | |||
2537 | spin_unlock(&dev->dev_reservation_lock); | 2492 | spin_unlock(&dev->dev_reservation_lock); |
2538 | 2493 | ||
2539 | if (pr_tmpl->pr_aptpl_active) { | 2494 | if (pr_tmpl->pr_aptpl_active) { |
2540 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 2495 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, |
2541 | &pr_reg->pr_aptpl_buf[0], | 2496 | &pr_reg->pr_aptpl_buf[0], |
2542 | pr_tmpl->pr_aptpl_buf_len); | 2497 | pr_tmpl->pr_aptpl_buf_len)) { |
2543 | if (!ret) | ||
2544 | pr_debug("SPC-3 PR: Updated APTPL metadata" | 2498 | pr_debug("SPC-3 PR: Updated APTPL metadata" |
2545 | " for RESERVE\n"); | 2499 | " for RESERVE\n"); |
2500 | } | ||
2546 | } | 2501 | } |
2547 | 2502 | ||
2503 | ret = 0; | ||
2504 | out_put_pr_reg: | ||
2548 | core_scsi3_put_pr_reg(pr_reg); | 2505 | core_scsi3_put_pr_reg(pr_reg); |
2549 | return 0; | 2506 | return ret; |
2550 | } | 2507 | } |
2551 | 2508 | ||
2552 | static int core_scsi3_emulate_pro_reserve( | 2509 | static sense_reason_t |
2553 | struct se_cmd *cmd, | 2510 | core_scsi3_emulate_pro_reserve(struct se_cmd *cmd, int type, int scope, |
2554 | int type, | 2511 | u64 res_key) |
2555 | int scope, | ||
2556 | u64 res_key) | ||
2557 | { | 2512 | { |
2558 | struct se_device *dev = cmd->se_dev; | ||
2559 | int ret = 0; | ||
2560 | |||
2561 | switch (type) { | 2513 | switch (type) { |
2562 | case PR_TYPE_WRITE_EXCLUSIVE: | 2514 | case PR_TYPE_WRITE_EXCLUSIVE: |
2563 | case PR_TYPE_EXCLUSIVE_ACCESS: | 2515 | case PR_TYPE_EXCLUSIVE_ACCESS: |
@@ -2565,16 +2517,12 @@ static int core_scsi3_emulate_pro_reserve( | |||
2565 | case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: | 2517 | case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: |
2566 | case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: | 2518 | case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: |
2567 | case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: | 2519 | case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: |
2568 | ret = core_scsi3_pro_reserve(cmd, dev, type, scope, res_key); | 2520 | return core_scsi3_pro_reserve(cmd, type, scope, res_key); |
2569 | break; | ||
2570 | default: | 2521 | default: |
2571 | pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:" | 2522 | pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:" |
2572 | " 0x%02x\n", type); | 2523 | " 0x%02x\n", type); |
2573 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 2524 | return TCM_INVALID_CDB_FIELD; |
2574 | return -EINVAL; | ||
2575 | } | 2525 | } |
2576 | |||
2577 | return ret; | ||
2578 | } | 2526 | } |
2579 | 2527 | ||
2580 | /* | 2528 | /* |
@@ -2612,23 +2560,21 @@ static void __core_scsi3_complete_pro_release( | |||
2612 | pr_reg->pr_res_holder = pr_reg->pr_res_type = pr_reg->pr_res_scope = 0; | 2560 | pr_reg->pr_res_holder = pr_reg->pr_res_type = pr_reg->pr_res_scope = 0; |
2613 | } | 2561 | } |
2614 | 2562 | ||
2615 | static int core_scsi3_emulate_pro_release( | 2563 | static sense_reason_t |
2616 | struct se_cmd *cmd, | 2564 | core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope, |
2617 | int type, | 2565 | u64 res_key) |
2618 | int scope, | ||
2619 | u64 res_key) | ||
2620 | { | 2566 | { |
2621 | struct se_device *dev = cmd->se_dev; | 2567 | struct se_device *dev = cmd->se_dev; |
2622 | struct se_session *se_sess = cmd->se_sess; | 2568 | struct se_session *se_sess = cmd->se_sess; |
2623 | struct se_lun *se_lun = cmd->se_lun; | 2569 | struct se_lun *se_lun = cmd->se_lun; |
2624 | struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder; | 2570 | struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder; |
2625 | struct t10_reservation *pr_tmpl = &dev->t10_pr; | 2571 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2626 | int ret, all_reg = 0; | 2572 | int all_reg = 0; |
2573 | sense_reason_t ret = 0; | ||
2627 | 2574 | ||
2628 | if (!se_sess || !se_lun) { | 2575 | if (!se_sess || !se_lun) { |
2629 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2576 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2630 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2577 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2631 | return -EINVAL; | ||
2632 | } | 2578 | } |
2633 | /* | 2579 | /* |
2634 | * Locate the existing *pr_reg via struct se_node_acl pointers | 2580 | * Locate the existing *pr_reg via struct se_node_acl pointers |
@@ -2637,8 +2583,7 @@ static int core_scsi3_emulate_pro_release( | |||
2637 | if (!pr_reg) { | 2583 | if (!pr_reg) { |
2638 | pr_err("SPC-3 PR: Unable to locate" | 2584 | pr_err("SPC-3 PR: Unable to locate" |
2639 | " PR_REGISTERED *pr_reg for RELEASE\n"); | 2585 | " PR_REGISTERED *pr_reg for RELEASE\n"); |
2640 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2586 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2641 | return -EINVAL; | ||
2642 | } | 2587 | } |
2643 | /* | 2588 | /* |
2644 | * From spc4r17 Section 5.7.11.2 Releasing: | 2589 | * From spc4r17 Section 5.7.11.2 Releasing: |
@@ -2659,7 +2604,6 @@ static int core_scsi3_emulate_pro_release( | |||
2659 | * No persistent reservation, return GOOD status. | 2604 | * No persistent reservation, return GOOD status. |
2660 | */ | 2605 | */ |
2661 | spin_unlock(&dev->dev_reservation_lock); | 2606 | spin_unlock(&dev->dev_reservation_lock); |
2662 | core_scsi3_put_pr_reg(pr_reg); | ||
2663 | return 0; | 2607 | return 0; |
2664 | } | 2608 | } |
2665 | if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || | 2609 | if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || |
@@ -2673,9 +2617,9 @@ static int core_scsi3_emulate_pro_release( | |||
2673 | * persistent reservation holder. return GOOD status. | 2617 | * persistent reservation holder. return GOOD status. |
2674 | */ | 2618 | */ |
2675 | spin_unlock(&dev->dev_reservation_lock); | 2619 | spin_unlock(&dev->dev_reservation_lock); |
2676 | core_scsi3_put_pr_reg(pr_reg); | 2620 | goto out_put_pr_reg; |
2677 | return 0; | ||
2678 | } | 2621 | } |
2622 | |||
2679 | /* | 2623 | /* |
2680 | * From spc4r17 Section 5.7.11.2 Releasing: | 2624 | * From spc4r17 Section 5.7.11.2 Releasing: |
2681 | * | 2625 | * |
@@ -2695,9 +2639,8 @@ static int core_scsi3_emulate_pro_release( | |||
2695 | " does not match existing SA REGISTER res_key:" | 2639 | " does not match existing SA REGISTER res_key:" |
2696 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 2640 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
2697 | spin_unlock(&dev->dev_reservation_lock); | 2641 | spin_unlock(&dev->dev_reservation_lock); |
2698 | core_scsi3_put_pr_reg(pr_reg); | 2642 | ret = TCM_RESERVATION_CONFLICT; |
2699 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2643 | goto out_put_pr_reg; |
2700 | return -EINVAL; | ||
2701 | } | 2644 | } |
2702 | /* | 2645 | /* |
2703 | * From spc4r17 Section 5.7.11.2 Releasing and above: | 2646 | * From spc4r17 Section 5.7.11.2 Releasing and above: |
@@ -2718,9 +2661,8 @@ static int core_scsi3_emulate_pro_release( | |||
2718 | pr_res_holder->pr_reg_nacl->initiatorname); | 2661 | pr_res_holder->pr_reg_nacl->initiatorname); |
2719 | 2662 | ||
2720 | spin_unlock(&dev->dev_reservation_lock); | 2663 | spin_unlock(&dev->dev_reservation_lock); |
2721 | core_scsi3_put_pr_reg(pr_reg); | 2664 | ret = TCM_RESERVATION_CONFLICT; |
2722 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2665 | goto out_put_pr_reg; |
2723 | return -EINVAL; | ||
2724 | } | 2666 | } |
2725 | /* | 2667 | /* |
2726 | * In response to a persistent reservation release request from the | 2668 | * In response to a persistent reservation release request from the |
@@ -2773,20 +2715,18 @@ static int core_scsi3_emulate_pro_release( | |||
2773 | 2715 | ||
2774 | write_aptpl: | 2716 | write_aptpl: |
2775 | if (pr_tmpl->pr_aptpl_active) { | 2717 | if (pr_tmpl->pr_aptpl_active) { |
2776 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 2718 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, |
2777 | &pr_reg->pr_aptpl_buf[0], | 2719 | &pr_reg->pr_aptpl_buf[0], pr_tmpl->pr_aptpl_buf_len)) { |
2778 | pr_tmpl->pr_aptpl_buf_len); | ||
2779 | if (!ret) | ||
2780 | pr_debug("SPC-3 PR: Updated APTPL metadata for RELEASE\n"); | 2720 | pr_debug("SPC-3 PR: Updated APTPL metadata for RELEASE\n"); |
2721 | } | ||
2781 | } | 2722 | } |
2782 | 2723 | out_put_pr_reg: | |
2783 | core_scsi3_put_pr_reg(pr_reg); | 2724 | core_scsi3_put_pr_reg(pr_reg); |
2784 | return 0; | 2725 | return ret; |
2785 | } | 2726 | } |
2786 | 2727 | ||
2787 | static int core_scsi3_emulate_pro_clear( | 2728 | static sense_reason_t |
2788 | struct se_cmd *cmd, | 2729 | core_scsi3_emulate_pro_clear(struct se_cmd *cmd, u64 res_key) |
2789 | u64 res_key) | ||
2790 | { | 2730 | { |
2791 | struct se_device *dev = cmd->se_dev; | 2731 | struct se_device *dev = cmd->se_dev; |
2792 | struct se_node_acl *pr_reg_nacl; | 2732 | struct se_node_acl *pr_reg_nacl; |
@@ -2803,8 +2743,7 @@ static int core_scsi3_emulate_pro_clear( | |||
2803 | if (!pr_reg_n) { | 2743 | if (!pr_reg_n) { |
2804 | pr_err("SPC-3 PR: Unable to locate" | 2744 | pr_err("SPC-3 PR: Unable to locate" |
2805 | " PR_REGISTERED *pr_reg for CLEAR\n"); | 2745 | " PR_REGISTERED *pr_reg for CLEAR\n"); |
2806 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2746 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2807 | return -EINVAL; | ||
2808 | } | 2747 | } |
2809 | /* | 2748 | /* |
2810 | * From spc4r17 section 5.7.11.6, Clearing: | 2749 | * From spc4r17 section 5.7.11.6, Clearing: |
@@ -2823,8 +2762,7 @@ static int core_scsi3_emulate_pro_clear( | |||
2823 | " existing SA REGISTER res_key:" | 2762 | " existing SA REGISTER res_key:" |
2824 | " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key); | 2763 | " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key); |
2825 | core_scsi3_put_pr_reg(pr_reg_n); | 2764 | core_scsi3_put_pr_reg(pr_reg_n); |
2826 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2765 | return TCM_RESERVATION_CONFLICT; |
2827 | return -EINVAL; | ||
2828 | } | 2766 | } |
2829 | /* | 2767 | /* |
2830 | * a) Release the persistent reservation, if any; | 2768 | * a) Release the persistent reservation, if any; |
@@ -2948,13 +2886,9 @@ static void core_scsi3_release_preempt_and_abort( | |||
2948 | } | 2886 | } |
2949 | } | 2887 | } |
2950 | 2888 | ||
2951 | static int core_scsi3_pro_preempt( | 2889 | static sense_reason_t |
2952 | struct se_cmd *cmd, | 2890 | core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, |
2953 | int type, | 2891 | u64 sa_res_key, int abort) |
2954 | int scope, | ||
2955 | u64 res_key, | ||
2956 | u64 sa_res_key, | ||
2957 | int abort) | ||
2958 | { | 2892 | { |
2959 | struct se_device *dev = cmd->se_dev; | 2893 | struct se_device *dev = cmd->se_dev; |
2960 | struct se_node_acl *pr_reg_nacl; | 2894 | struct se_node_acl *pr_reg_nacl; |
@@ -2964,12 +2898,10 @@ static int core_scsi3_pro_preempt( | |||
2964 | struct t10_reservation *pr_tmpl = &dev->t10_pr; | 2898 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2965 | u32 pr_res_mapped_lun = 0; | 2899 | u32 pr_res_mapped_lun = 0; |
2966 | int all_reg = 0, calling_it_nexus = 0, released_regs = 0; | 2900 | int all_reg = 0, calling_it_nexus = 0, released_regs = 0; |
2967 | int prh_type = 0, prh_scope = 0, ret; | 2901 | int prh_type = 0, prh_scope = 0; |
2968 | 2902 | ||
2969 | if (!se_sess) { | 2903 | if (!se_sess) |
2970 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2904 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2971 | return -EINVAL; | ||
2972 | } | ||
2973 | 2905 | ||
2974 | pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, | 2906 | pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, |
2975 | se_sess); | 2907 | se_sess); |
@@ -2977,19 +2909,16 @@ static int core_scsi3_pro_preempt( | |||
2977 | pr_err("SPC-3 PR: Unable to locate" | 2909 | pr_err("SPC-3 PR: Unable to locate" |
2978 | " PR_REGISTERED *pr_reg for PREEMPT%s\n", | 2910 | " PR_REGISTERED *pr_reg for PREEMPT%s\n", |
2979 | (abort) ? "_AND_ABORT" : ""); | 2911 | (abort) ? "_AND_ABORT" : ""); |
2980 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2912 | return TCM_RESERVATION_CONFLICT; |
2981 | return -EINVAL; | ||
2982 | } | 2913 | } |
2983 | if (pr_reg_n->pr_res_key != res_key) { | 2914 | if (pr_reg_n->pr_res_key != res_key) { |
2984 | core_scsi3_put_pr_reg(pr_reg_n); | 2915 | core_scsi3_put_pr_reg(pr_reg_n); |
2985 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2916 | return TCM_RESERVATION_CONFLICT; |
2986 | return -EINVAL; | ||
2987 | } | 2917 | } |
2988 | if (scope != PR_SCOPE_LU_SCOPE) { | 2918 | if (scope != PR_SCOPE_LU_SCOPE) { |
2989 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); | 2919 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); |
2990 | core_scsi3_put_pr_reg(pr_reg_n); | 2920 | core_scsi3_put_pr_reg(pr_reg_n); |
2991 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 2921 | return TCM_INVALID_PARAMETER_LIST; |
2992 | return -EINVAL; | ||
2993 | } | 2922 | } |
2994 | 2923 | ||
2995 | spin_lock(&dev->dev_reservation_lock); | 2924 | spin_lock(&dev->dev_reservation_lock); |
@@ -3002,8 +2931,7 @@ static int core_scsi3_pro_preempt( | |||
3002 | if (!all_reg && !sa_res_key) { | 2931 | if (!all_reg && !sa_res_key) { |
3003 | spin_unlock(&dev->dev_reservation_lock); | 2932 | spin_unlock(&dev->dev_reservation_lock); |
3004 | core_scsi3_put_pr_reg(pr_reg_n); | 2933 | core_scsi3_put_pr_reg(pr_reg_n); |
3005 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 2934 | return TCM_INVALID_PARAMETER_LIST; |
3006 | return -EINVAL; | ||
3007 | } | 2935 | } |
3008 | /* | 2936 | /* |
3009 | * From spc4r17, section 5.7.11.4.4 Removing Registrations: | 2937 | * From spc4r17, section 5.7.11.4.4 Removing Registrations: |
@@ -3097,8 +3025,7 @@ static int core_scsi3_pro_preempt( | |||
3097 | if (!released_regs) { | 3025 | if (!released_regs) { |
3098 | spin_unlock(&dev->dev_reservation_lock); | 3026 | spin_unlock(&dev->dev_reservation_lock); |
3099 | core_scsi3_put_pr_reg(pr_reg_n); | 3027 | core_scsi3_put_pr_reg(pr_reg_n); |
3100 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 3028 | return TCM_RESERVATION_CONFLICT; |
3101 | return -EINVAL; | ||
3102 | } | 3029 | } |
3103 | /* | 3030 | /* |
3104 | * For an existing all registrants type reservation | 3031 | * For an existing all registrants type reservation |
@@ -3117,13 +3044,13 @@ static int core_scsi3_pro_preempt( | |||
3117 | spin_unlock(&dev->dev_reservation_lock); | 3044 | spin_unlock(&dev->dev_reservation_lock); |
3118 | 3045 | ||
3119 | if (pr_tmpl->pr_aptpl_active) { | 3046 | if (pr_tmpl->pr_aptpl_active) { |
3120 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 3047 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, |
3121 | &pr_reg_n->pr_aptpl_buf[0], | 3048 | &pr_reg_n->pr_aptpl_buf[0], |
3122 | pr_tmpl->pr_aptpl_buf_len); | 3049 | pr_tmpl->pr_aptpl_buf_len)) { |
3123 | if (!ret) | ||
3124 | pr_debug("SPC-3 PR: Updated APTPL" | 3050 | pr_debug("SPC-3 PR: Updated APTPL" |
3125 | " metadata for PREEMPT%s\n", (abort) ? | 3051 | " metadata for PREEMPT%s\n", (abort) ? |
3126 | "_AND_ABORT" : ""); | 3052 | "_AND_ABORT" : ""); |
3053 | } | ||
3127 | } | 3054 | } |
3128 | 3055 | ||
3129 | core_scsi3_put_pr_reg(pr_reg_n); | 3056 | core_scsi3_put_pr_reg(pr_reg_n); |
@@ -3253,12 +3180,12 @@ static int core_scsi3_pro_preempt( | |||
3253 | } | 3180 | } |
3254 | 3181 | ||
3255 | if (pr_tmpl->pr_aptpl_active) { | 3182 | if (pr_tmpl->pr_aptpl_active) { |
3256 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 3183 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, |
3257 | &pr_reg_n->pr_aptpl_buf[0], | 3184 | &pr_reg_n->pr_aptpl_buf[0], |
3258 | pr_tmpl->pr_aptpl_buf_len); | 3185 | pr_tmpl->pr_aptpl_buf_len)) { |
3259 | if (!ret) | ||
3260 | pr_debug("SPC-3 PR: Updated APTPL metadata for PREEMPT" | 3186 | pr_debug("SPC-3 PR: Updated APTPL metadata for PREEMPT" |
3261 | "%s\n", (abort) ? "_AND_ABORT" : ""); | 3187 | "%s\n", abort ? "_AND_ABORT" : ""); |
3188 | } | ||
3262 | } | 3189 | } |
3263 | 3190 | ||
3264 | core_scsi3_put_pr_reg(pr_reg_n); | 3191 | core_scsi3_put_pr_reg(pr_reg_n); |
@@ -3266,16 +3193,10 @@ static int core_scsi3_pro_preempt( | |||
3266 | return 0; | 3193 | return 0; |
3267 | } | 3194 | } |
3268 | 3195 | ||
3269 | static int core_scsi3_emulate_pro_preempt( | 3196 | static sense_reason_t |
3270 | struct se_cmd *cmd, | 3197 | core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope, |
3271 | int type, | 3198 | u64 res_key, u64 sa_res_key, int abort) |
3272 | int scope, | ||
3273 | u64 res_key, | ||
3274 | u64 sa_res_key, | ||
3275 | int abort) | ||
3276 | { | 3199 | { |
3277 | int ret = 0; | ||
3278 | |||
3279 | switch (type) { | 3200 | switch (type) { |
3280 | case PR_TYPE_WRITE_EXCLUSIVE: | 3201 | case PR_TYPE_WRITE_EXCLUSIVE: |
3281 | case PR_TYPE_EXCLUSIVE_ACCESS: | 3202 | case PR_TYPE_EXCLUSIVE_ACCESS: |
@@ -3283,26 +3204,19 @@ static int core_scsi3_emulate_pro_preempt( | |||
3283 | case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: | 3204 | case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: |
3284 | case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: | 3205 | case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: |
3285 | case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: | 3206 | case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: |
3286 | ret = core_scsi3_pro_preempt(cmd, type, scope, | 3207 | return core_scsi3_pro_preempt(cmd, type, scope, res_key, |
3287 | res_key, sa_res_key, abort); | 3208 | sa_res_key, abort); |
3288 | break; | ||
3289 | default: | 3209 | default: |
3290 | pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" | 3210 | pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" |
3291 | " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); | 3211 | " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); |
3292 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3212 | return TCM_INVALID_CDB_FIELD; |
3293 | return -EINVAL; | ||
3294 | } | 3213 | } |
3295 | |||
3296 | return ret; | ||
3297 | } | 3214 | } |
3298 | 3215 | ||
3299 | 3216 | ||
3300 | static int core_scsi3_emulate_pro_register_and_move( | 3217 | static sense_reason_t |
3301 | struct se_cmd *cmd, | 3218 | core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, |
3302 | u64 res_key, | 3219 | u64 sa_res_key, int aptpl, int unreg) |
3303 | u64 sa_res_key, | ||
3304 | int aptpl, | ||
3305 | int unreg) | ||
3306 | { | 3220 | { |
3307 | struct se_session *se_sess = cmd->se_sess; | 3221 | struct se_session *se_sess = cmd->se_sess; |
3308 | struct se_device *dev = cmd->se_dev; | 3222 | struct se_device *dev = cmd->se_dev; |
@@ -3318,15 +3232,16 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3318 | unsigned char *initiator_str; | 3232 | unsigned char *initiator_str; |
3319 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; | 3233 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; |
3320 | u32 tid_len, tmp_tid_len; | 3234 | u32 tid_len, tmp_tid_len; |
3321 | int new_reg = 0, type, scope, ret, matching_iname, prf_isid; | 3235 | int new_reg = 0, type, scope, matching_iname, prf_isid; |
3236 | sense_reason_t ret; | ||
3322 | unsigned short rtpi; | 3237 | unsigned short rtpi; |
3323 | unsigned char proto_ident; | 3238 | unsigned char proto_ident; |
3324 | 3239 | ||
3325 | if (!se_sess || !se_lun) { | 3240 | if (!se_sess || !se_lun) { |
3326 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 3241 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
3327 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3242 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3328 | return -EINVAL; | ||
3329 | } | 3243 | } |
3244 | |||
3330 | memset(dest_iport, 0, 64); | 3245 | memset(dest_iport, 0, 64); |
3331 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 3246 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
3332 | se_tpg = se_sess->se_tpg; | 3247 | se_tpg = se_sess->se_tpg; |
@@ -3342,8 +3257,7 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3342 | if (!pr_reg) { | 3257 | if (!pr_reg) { |
3343 | pr_err("SPC-3 PR: Unable to locate PR_REGISTERED" | 3258 | pr_err("SPC-3 PR: Unable to locate PR_REGISTERED" |
3344 | " *pr_reg for REGISTER_AND_MOVE\n"); | 3259 | " *pr_reg for REGISTER_AND_MOVE\n"); |
3345 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3260 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3346 | return -EINVAL; | ||
3347 | } | 3261 | } |
3348 | /* | 3262 | /* |
3349 | * The provided reservation key much match the existing reservation key | 3263 | * The provided reservation key much match the existing reservation key |
@@ -3353,9 +3267,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3353 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received" | 3267 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received" |
3354 | " res_key: 0x%016Lx does not match existing SA REGISTER" | 3268 | " res_key: 0x%016Lx does not match existing SA REGISTER" |
3355 | " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 3269 | " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
3356 | core_scsi3_put_pr_reg(pr_reg); | 3270 | ret = TCM_RESERVATION_CONFLICT; |
3357 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 3271 | goto out_put_pr_reg; |
3358 | return -EINVAL; | ||
3359 | } | 3272 | } |
3360 | /* | 3273 | /* |
3361 | * The service active reservation key needs to be non zero | 3274 | * The service active reservation key needs to be non zero |
@@ -3363,9 +3276,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3363 | if (!sa_res_key) { | 3276 | if (!sa_res_key) { |
3364 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero" | 3277 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero" |
3365 | " sa_res_key\n"); | 3278 | " sa_res_key\n"); |
3366 | core_scsi3_put_pr_reg(pr_reg); | 3279 | ret = TCM_INVALID_PARAMETER_LIST; |
3367 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3280 | goto out_put_pr_reg; |
3368 | return -EINVAL; | ||
3369 | } | 3281 | } |
3370 | 3282 | ||
3371 | /* | 3283 | /* |
@@ -3374,6 +3286,11 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3374 | * information. | 3286 | * information. |
3375 | */ | 3287 | */ |
3376 | buf = transport_kmap_data_sg(cmd); | 3288 | buf = transport_kmap_data_sg(cmd); |
3289 | if (!buf) { | ||
3290 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
3291 | goto out_put_pr_reg; | ||
3292 | } | ||
3293 | |||
3377 | rtpi = (buf[18] & 0xff) << 8; | 3294 | rtpi = (buf[18] & 0xff) << 8; |
3378 | rtpi |= buf[19] & 0xff; | 3295 | rtpi |= buf[19] & 0xff; |
3379 | tid_len = (buf[20] & 0xff) << 24; | 3296 | tid_len = (buf[20] & 0xff) << 24; |
@@ -3387,9 +3304,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3387 | pr_err("SPC-3 PR: Illegal tid_len: %u + 24 byte header" | 3304 | pr_err("SPC-3 PR: Illegal tid_len: %u + 24 byte header" |
3388 | " does not equal CDB data_length: %u\n", tid_len, | 3305 | " does not equal CDB data_length: %u\n", tid_len, |
3389 | cmd->data_length); | 3306 | cmd->data_length); |
3390 | core_scsi3_put_pr_reg(pr_reg); | 3307 | ret = TCM_INVALID_PARAMETER_LIST; |
3391 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3308 | goto out_put_pr_reg; |
3392 | return -EINVAL; | ||
3393 | } | 3309 | } |
3394 | 3310 | ||
3395 | spin_lock(&dev->se_port_lock); | 3311 | spin_lock(&dev->se_port_lock); |
@@ -3407,15 +3323,13 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3407 | smp_mb__after_atomic_inc(); | 3323 | smp_mb__after_atomic_inc(); |
3408 | spin_unlock(&dev->se_port_lock); | 3324 | spin_unlock(&dev->se_port_lock); |
3409 | 3325 | ||
3410 | ret = core_scsi3_tpg_depend_item(dest_se_tpg); | 3326 | if (core_scsi3_tpg_depend_item(dest_se_tpg)) { |
3411 | if (ret != 0) { | ||
3412 | pr_err("core_scsi3_tpg_depend_item() failed" | 3327 | pr_err("core_scsi3_tpg_depend_item() failed" |
3413 | " for dest_se_tpg\n"); | 3328 | " for dest_se_tpg\n"); |
3414 | atomic_dec(&dest_se_tpg->tpg_pr_ref_count); | 3329 | atomic_dec(&dest_se_tpg->tpg_pr_ref_count); |
3415 | smp_mb__after_atomic_dec(); | 3330 | smp_mb__after_atomic_dec(); |
3416 | core_scsi3_put_pr_reg(pr_reg); | 3331 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3417 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3332 | goto out_put_pr_reg; |
3418 | return -EINVAL; | ||
3419 | } | 3333 | } |
3420 | 3334 | ||
3421 | spin_lock(&dev->se_port_lock); | 3335 | spin_lock(&dev->se_port_lock); |
@@ -3427,12 +3341,15 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3427 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" | 3341 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" |
3428 | " fabric ops from Relative Target Port Identifier:" | 3342 | " fabric ops from Relative Target Port Identifier:" |
3429 | " %hu\n", rtpi); | 3343 | " %hu\n", rtpi); |
3430 | core_scsi3_put_pr_reg(pr_reg); | 3344 | ret = TCM_INVALID_PARAMETER_LIST; |
3431 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3345 | goto out_put_pr_reg; |
3432 | return -EINVAL; | ||
3433 | } | 3346 | } |
3434 | 3347 | ||
3435 | buf = transport_kmap_data_sg(cmd); | 3348 | buf = transport_kmap_data_sg(cmd); |
3349 | if (!buf) { | ||
3350 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
3351 | goto out_put_pr_reg; | ||
3352 | } | ||
3436 | proto_ident = (buf[24] & 0x0f); | 3353 | proto_ident = (buf[24] & 0x0f); |
3437 | 3354 | ||
3438 | pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:" | 3355 | pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:" |
@@ -3444,16 +3361,14 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3444 | " from fabric: %s\n", proto_ident, | 3361 | " from fabric: %s\n", proto_ident, |
3445 | dest_tf_ops->get_fabric_proto_ident(dest_se_tpg), | 3362 | dest_tf_ops->get_fabric_proto_ident(dest_se_tpg), |
3446 | dest_tf_ops->get_fabric_name()); | 3363 | dest_tf_ops->get_fabric_name()); |
3447 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3364 | ret = TCM_INVALID_PARAMETER_LIST; |
3448 | ret = -EINVAL; | ||
3449 | goto out; | 3365 | goto out; |
3450 | } | 3366 | } |
3451 | if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) { | 3367 | if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) { |
3452 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not" | 3368 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not" |
3453 | " containg a valid tpg_parse_pr_out_transport_id" | 3369 | " containg a valid tpg_parse_pr_out_transport_id" |
3454 | " function pointer\n"); | 3370 | " function pointer\n"); |
3455 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3371 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3456 | ret = -EINVAL; | ||
3457 | goto out; | 3372 | goto out; |
3458 | } | 3373 | } |
3459 | initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg, | 3374 | initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg, |
@@ -3461,8 +3376,7 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3461 | if (!initiator_str) { | 3376 | if (!initiator_str) { |
3462 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" | 3377 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" |
3463 | " initiator_str from Transport ID\n"); | 3378 | " initiator_str from Transport ID\n"); |
3464 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3379 | ret = TCM_INVALID_PARAMETER_LIST; |
3465 | ret = -EINVAL; | ||
3466 | goto out; | 3380 | goto out; |
3467 | } | 3381 | } |
3468 | 3382 | ||
@@ -3491,8 +3405,7 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3491 | pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s" | 3405 | pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s" |
3492 | " matches: %s on received I_T Nexus\n", initiator_str, | 3406 | " matches: %s on received I_T Nexus\n", initiator_str, |
3493 | pr_reg_nacl->initiatorname); | 3407 | pr_reg_nacl->initiatorname); |
3494 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3408 | ret = TCM_INVALID_PARAMETER_LIST; |
3495 | ret = -EINVAL; | ||
3496 | goto out; | 3409 | goto out; |
3497 | } | 3410 | } |
3498 | if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) { | 3411 | if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) { |
@@ -3500,8 +3413,7 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3500 | " matches: %s %s on received I_T Nexus\n", | 3413 | " matches: %s %s on received I_T Nexus\n", |
3501 | initiator_str, iport_ptr, pr_reg_nacl->initiatorname, | 3414 | initiator_str, iport_ptr, pr_reg_nacl->initiatorname, |
3502 | pr_reg->pr_reg_isid); | 3415 | pr_reg->pr_reg_isid); |
3503 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3416 | ret = TCM_INVALID_PARAMETER_LIST; |
3504 | ret = -EINVAL; | ||
3505 | goto out; | 3417 | goto out; |
3506 | } | 3418 | } |
3507 | after_iport_check: | 3419 | after_iport_check: |
@@ -3521,19 +3433,17 @@ after_iport_check: | |||
3521 | pr_err("Unable to locate %s dest_node_acl for" | 3433 | pr_err("Unable to locate %s dest_node_acl for" |
3522 | " TransportID%s\n", dest_tf_ops->get_fabric_name(), | 3434 | " TransportID%s\n", dest_tf_ops->get_fabric_name(), |
3523 | initiator_str); | 3435 | initiator_str); |
3524 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3436 | ret = TCM_INVALID_PARAMETER_LIST; |
3525 | ret = -EINVAL; | ||
3526 | goto out; | 3437 | goto out; |
3527 | } | 3438 | } |
3528 | ret = core_scsi3_nodeacl_depend_item(dest_node_acl); | 3439 | |
3529 | if (ret != 0) { | 3440 | if (core_scsi3_nodeacl_depend_item(dest_node_acl)) { |
3530 | pr_err("core_scsi3_nodeacl_depend_item() for" | 3441 | pr_err("core_scsi3_nodeacl_depend_item() for" |
3531 | " dest_node_acl\n"); | 3442 | " dest_node_acl\n"); |
3532 | atomic_dec(&dest_node_acl->acl_pr_ref_count); | 3443 | atomic_dec(&dest_node_acl->acl_pr_ref_count); |
3533 | smp_mb__after_atomic_dec(); | 3444 | smp_mb__after_atomic_dec(); |
3534 | dest_node_acl = NULL; | 3445 | dest_node_acl = NULL; |
3535 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3446 | ret = TCM_INVALID_PARAMETER_LIST; |
3536 | ret = -EINVAL; | ||
3537 | goto out; | 3447 | goto out; |
3538 | } | 3448 | } |
3539 | 3449 | ||
@@ -3549,19 +3459,16 @@ after_iport_check: | |||
3549 | if (!dest_se_deve) { | 3459 | if (!dest_se_deve) { |
3550 | pr_err("Unable to locate %s dest_se_deve from RTPI:" | 3460 | pr_err("Unable to locate %s dest_se_deve from RTPI:" |
3551 | " %hu\n", dest_tf_ops->get_fabric_name(), rtpi); | 3461 | " %hu\n", dest_tf_ops->get_fabric_name(), rtpi); |
3552 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3462 | ret = TCM_INVALID_PARAMETER_LIST; |
3553 | ret = -EINVAL; | ||
3554 | goto out; | 3463 | goto out; |
3555 | } | 3464 | } |
3556 | 3465 | ||
3557 | ret = core_scsi3_lunacl_depend_item(dest_se_deve); | 3466 | if (core_scsi3_lunacl_depend_item(dest_se_deve)) { |
3558 | if (ret < 0) { | ||
3559 | pr_err("core_scsi3_lunacl_depend_item() failed\n"); | 3467 | pr_err("core_scsi3_lunacl_depend_item() failed\n"); |
3560 | atomic_dec(&dest_se_deve->pr_ref_count); | 3468 | atomic_dec(&dest_se_deve->pr_ref_count); |
3561 | smp_mb__after_atomic_dec(); | 3469 | smp_mb__after_atomic_dec(); |
3562 | dest_se_deve = NULL; | 3470 | dest_se_deve = NULL; |
3563 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3471 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3564 | ret = -EINVAL; | ||
3565 | goto out; | 3472 | goto out; |
3566 | } | 3473 | } |
3567 | 3474 | ||
@@ -3580,8 +3487,7 @@ after_iport_check: | |||
3580 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation" | 3487 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation" |
3581 | " currently held\n"); | 3488 | " currently held\n"); |
3582 | spin_unlock(&dev->dev_reservation_lock); | 3489 | spin_unlock(&dev->dev_reservation_lock); |
3583 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3490 | ret = TCM_INVALID_CDB_FIELD; |
3584 | ret = -EINVAL; | ||
3585 | goto out; | 3491 | goto out; |
3586 | } | 3492 | } |
3587 | /* | 3493 | /* |
@@ -3594,8 +3500,7 @@ after_iport_check: | |||
3594 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" | 3500 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" |
3595 | " Nexus is not reservation holder\n"); | 3501 | " Nexus is not reservation holder\n"); |
3596 | spin_unlock(&dev->dev_reservation_lock); | 3502 | spin_unlock(&dev->dev_reservation_lock); |
3597 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 3503 | ret = TCM_RESERVATION_CONFLICT; |
3598 | ret = -EINVAL; | ||
3599 | goto out; | 3504 | goto out; |
3600 | } | 3505 | } |
3601 | /* | 3506 | /* |
@@ -3613,8 +3518,7 @@ after_iport_check: | |||
3613 | " reservation for type: %s\n", | 3518 | " reservation for type: %s\n", |
3614 | core_scsi3_pr_dump_type(pr_res_holder->pr_res_type)); | 3519 | core_scsi3_pr_dump_type(pr_res_holder->pr_res_type)); |
3615 | spin_unlock(&dev->dev_reservation_lock); | 3520 | spin_unlock(&dev->dev_reservation_lock); |
3616 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 3521 | ret = TCM_RESERVATION_CONFLICT; |
3617 | ret = -EINVAL; | ||
3618 | goto out; | 3522 | goto out; |
3619 | } | 3523 | } |
3620 | pr_res_nacl = pr_res_holder->pr_reg_nacl; | 3524 | pr_res_nacl = pr_res_holder->pr_reg_nacl; |
@@ -3646,13 +3550,11 @@ after_iport_check: | |||
3646 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, | 3550 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, |
3647 | iport_ptr); | 3551 | iport_ptr); |
3648 | if (!dest_pr_reg) { | 3552 | if (!dest_pr_reg) { |
3649 | ret = core_scsi3_alloc_registration(cmd->se_dev, | 3553 | if (core_scsi3_alloc_registration(cmd->se_dev, |
3650 | dest_node_acl, dest_se_deve, iport_ptr, | 3554 | dest_node_acl, dest_se_deve, iport_ptr, |
3651 | sa_res_key, 0, aptpl, 2, 1); | 3555 | sa_res_key, 0, aptpl, 2, 1)) { |
3652 | if (ret != 0) { | ||
3653 | spin_unlock(&dev->dev_reservation_lock); | 3556 | spin_unlock(&dev->dev_reservation_lock); |
3654 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3557 | ret = TCM_INVALID_PARAMETER_LIST; |
3655 | ret = -EINVAL; | ||
3656 | goto out; | 3558 | goto out; |
3657 | } | 3559 | } |
3658 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, | 3560 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, |
@@ -3723,12 +3625,12 @@ after_iport_check: | |||
3723 | " REGISTER_AND_MOVE\n"); | 3625 | " REGISTER_AND_MOVE\n"); |
3724 | } else { | 3626 | } else { |
3725 | pr_tmpl->pr_aptpl_active = 1; | 3627 | pr_tmpl->pr_aptpl_active = 1; |
3726 | ret = core_scsi3_update_and_write_aptpl(cmd->se_dev, | 3628 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, |
3727 | &dest_pr_reg->pr_aptpl_buf[0], | 3629 | &dest_pr_reg->pr_aptpl_buf[0], |
3728 | pr_tmpl->pr_aptpl_buf_len); | 3630 | pr_tmpl->pr_aptpl_buf_len)) { |
3729 | if (!ret) | ||
3730 | pr_debug("SPC-3 PR: Set APTPL Bit Activated for" | 3631 | pr_debug("SPC-3 PR: Set APTPL Bit Activated for" |
3731 | " REGISTER_AND_MOVE\n"); | 3632 | " REGISTER_AND_MOVE\n"); |
3633 | } | ||
3732 | } | 3634 | } |
3733 | 3635 | ||
3734 | transport_kunmap_data_sg(cmd); | 3636 | transport_kunmap_data_sg(cmd); |
@@ -3743,6 +3645,8 @@ out: | |||
3743 | if (dest_node_acl) | 3645 | if (dest_node_acl) |
3744 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 3646 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
3745 | core_scsi3_tpg_undepend_item(dest_se_tpg); | 3647 | core_scsi3_tpg_undepend_item(dest_se_tpg); |
3648 | |||
3649 | out_put_pr_reg: | ||
3746 | core_scsi3_put_pr_reg(pr_reg); | 3650 | core_scsi3_put_pr_reg(pr_reg); |
3747 | return ret; | 3651 | return ret; |
3748 | } | 3652 | } |
@@ -3760,14 +3664,15 @@ static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb) | |||
3760 | /* | 3664 | /* |
3761 | * See spc4r17 section 6.14 Table 170 | 3665 | * See spc4r17 section 6.14 Table 170 |
3762 | */ | 3666 | */ |
3763 | int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | 3667 | sense_reason_t |
3668 | target_scsi3_emulate_pr_out(struct se_cmd *cmd) | ||
3764 | { | 3669 | { |
3765 | unsigned char *cdb = &cmd->t_task_cdb[0]; | 3670 | unsigned char *cdb = &cmd->t_task_cdb[0]; |
3766 | unsigned char *buf; | 3671 | unsigned char *buf; |
3767 | u64 res_key, sa_res_key; | 3672 | u64 res_key, sa_res_key; |
3768 | int sa, scope, type, aptpl; | 3673 | int sa, scope, type, aptpl; |
3769 | int spec_i_pt = 0, all_tg_pt = 0, unreg = 0; | 3674 | int spec_i_pt = 0, all_tg_pt = 0, unreg = 0; |
3770 | int ret; | 3675 | sense_reason_t ret; |
3771 | 3676 | ||
3772 | /* | 3677 | /* |
3773 | * Following spc2r20 5.5.1 Reservations overview: | 3678 | * Following spc2r20 5.5.1 Reservations overview: |
@@ -3782,28 +3687,22 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3782 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" | 3687 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" |
3783 | " SPC-2 reservation is held, returning" | 3688 | " SPC-2 reservation is held, returning" |
3784 | " RESERVATION_CONFLICT\n"); | 3689 | " RESERVATION_CONFLICT\n"); |
3785 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 3690 | return TCM_RESERVATION_CONFLICT; |
3786 | ret = -EINVAL; | ||
3787 | goto out; | ||
3788 | } | 3691 | } |
3789 | 3692 | ||
3790 | /* | 3693 | /* |
3791 | * FIXME: A NULL struct se_session pointer means an this is not coming from | 3694 | * FIXME: A NULL struct se_session pointer means an this is not coming from |
3792 | * a $FABRIC_MOD's nexus, but from internal passthrough ops. | 3695 | * a $FABRIC_MOD's nexus, but from internal passthrough ops. |
3793 | */ | 3696 | */ |
3794 | if (!cmd->se_sess) { | 3697 | if (!cmd->se_sess) |
3795 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3698 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3796 | ret = -EINVAL; | ||
3797 | goto out; | ||
3798 | } | ||
3799 | 3699 | ||
3800 | if (cmd->data_length < 24) { | 3700 | if (cmd->data_length < 24) { |
3801 | pr_warn("SPC-PR: Received PR OUT parameter list" | 3701 | pr_warn("SPC-PR: Received PR OUT parameter list" |
3802 | " length too small: %u\n", cmd->data_length); | 3702 | " length too small: %u\n", cmd->data_length); |
3803 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3703 | return TCM_INVALID_PARAMETER_LIST; |
3804 | ret = -EINVAL; | ||
3805 | goto out; | ||
3806 | } | 3704 | } |
3705 | |||
3807 | /* | 3706 | /* |
3808 | * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB) | 3707 | * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB) |
3809 | */ | 3708 | */ |
@@ -3812,6 +3711,9 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3812 | type = (cdb[2] & 0x0f); | 3711 | type = (cdb[2] & 0x0f); |
3813 | 3712 | ||
3814 | buf = transport_kmap_data_sg(cmd); | 3713 | buf = transport_kmap_data_sg(cmd); |
3714 | if (!buf) | ||
3715 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
3716 | |||
3815 | /* | 3717 | /* |
3816 | * From PERSISTENT_RESERVE_OUT parameter list (payload) | 3718 | * From PERSISTENT_RESERVE_OUT parameter list (payload) |
3817 | */ | 3719 | */ |
@@ -3835,11 +3737,8 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3835 | /* | 3737 | /* |
3836 | * SPEC_I_PT=1 is only valid for Service action: REGISTER | 3738 | * SPEC_I_PT=1 is only valid for Service action: REGISTER |
3837 | */ | 3739 | */ |
3838 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) { | 3740 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) |
3839 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3741 | return TCM_INVALID_PARAMETER_LIST; |
3840 | ret = -EINVAL; | ||
3841 | goto out; | ||
3842 | } | ||
3843 | 3742 | ||
3844 | /* | 3743 | /* |
3845 | * From spc4r17 section 6.14: | 3744 | * From spc4r17 section 6.14: |
@@ -3854,10 +3753,9 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3854 | (cmd->data_length != 24)) { | 3753 | (cmd->data_length != 24)) { |
3855 | pr_warn("SPC-PR: Received PR OUT illegal parameter" | 3754 | pr_warn("SPC-PR: Received PR OUT illegal parameter" |
3856 | " list length: %u\n", cmd->data_length); | 3755 | " list length: %u\n", cmd->data_length); |
3857 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 3756 | return TCM_INVALID_PARAMETER_LIST; |
3858 | ret = -EINVAL; | ||
3859 | goto out; | ||
3860 | } | 3757 | } |
3758 | |||
3861 | /* | 3759 | /* |
3862 | * (core_scsi3_emulate_pro_* function parameters | 3760 | * (core_scsi3_emulate_pro_* function parameters |
3863 | * are defined by spc4r17 Table 174: | 3761 | * are defined by spc4r17 Table 174: |
@@ -3896,12 +3794,9 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3896 | default: | 3794 | default: |
3897 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" | 3795 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" |
3898 | " action: 0x%02x\n", cdb[1] & 0x1f); | 3796 | " action: 0x%02x\n", cdb[1] & 0x1f); |
3899 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3797 | return TCM_INVALID_CDB_FIELD; |
3900 | ret = -EINVAL; | ||
3901 | break; | ||
3902 | } | 3798 | } |
3903 | 3799 | ||
3904 | out: | ||
3905 | if (!ret) | 3800 | if (!ret) |
3906 | target_complete_cmd(cmd, GOOD); | 3801 | target_complete_cmd(cmd, GOOD); |
3907 | return ret; | 3802 | return ret; |
@@ -3912,7 +3807,8 @@ out: | |||
3912 | * | 3807 | * |
3913 | * See spc4r17 section 5.7.6.2 and section 6.13.2, Table 160 | 3808 | * See spc4r17 section 5.7.6.2 and section 6.13.2, Table 160 |
3914 | */ | 3809 | */ |
3915 | static int core_scsi3_pri_read_keys(struct se_cmd *cmd) | 3810 | static sense_reason_t |
3811 | core_scsi3_pri_read_keys(struct se_cmd *cmd) | ||
3916 | { | 3812 | { |
3917 | struct se_device *dev = cmd->se_dev; | 3813 | struct se_device *dev = cmd->se_dev; |
3918 | struct t10_pr_registration *pr_reg; | 3814 | struct t10_pr_registration *pr_reg; |
@@ -3922,11 +3818,13 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd) | |||
3922 | if (cmd->data_length < 8) { | 3818 | if (cmd->data_length < 8) { |
3923 | pr_err("PRIN SA READ_KEYS SCSI Data Length: %u" | 3819 | pr_err("PRIN SA READ_KEYS SCSI Data Length: %u" |
3924 | " too small\n", cmd->data_length); | 3820 | " too small\n", cmd->data_length); |
3925 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3821 | return TCM_INVALID_CDB_FIELD; |
3926 | return -EINVAL; | ||
3927 | } | 3822 | } |
3928 | 3823 | ||
3929 | buf = transport_kmap_data_sg(cmd); | 3824 | buf = transport_kmap_data_sg(cmd); |
3825 | if (!buf) | ||
3826 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
3827 | |||
3930 | buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); | 3828 | buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); |
3931 | buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); | 3829 | buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); |
3932 | buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff); | 3830 | buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff); |
@@ -3970,7 +3868,8 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd) | |||
3970 | * | 3868 | * |
3971 | * See spc4r17 section 5.7.6.3 and section 6.13.3.2 Table 161 and 162 | 3869 | * See spc4r17 section 5.7.6.3 and section 6.13.3.2 Table 161 and 162 |
3972 | */ | 3870 | */ |
3973 | static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) | 3871 | static sense_reason_t |
3872 | core_scsi3_pri_read_reservation(struct se_cmd *cmd) | ||
3974 | { | 3873 | { |
3975 | struct se_device *dev = cmd->se_dev; | 3874 | struct se_device *dev = cmd->se_dev; |
3976 | struct t10_pr_registration *pr_reg; | 3875 | struct t10_pr_registration *pr_reg; |
@@ -3981,11 +3880,13 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) | |||
3981 | if (cmd->data_length < 8) { | 3880 | if (cmd->data_length < 8) { |
3982 | pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" | 3881 | pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" |
3983 | " too small\n", cmd->data_length); | 3882 | " too small\n", cmd->data_length); |
3984 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3883 | return TCM_INVALID_CDB_FIELD; |
3985 | return -EINVAL; | ||
3986 | } | 3884 | } |
3987 | 3885 | ||
3988 | buf = transport_kmap_data_sg(cmd); | 3886 | buf = transport_kmap_data_sg(cmd); |
3887 | if (!buf) | ||
3888 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
3889 | |||
3989 | buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); | 3890 | buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); |
3990 | buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); | 3891 | buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); |
3991 | buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff); | 3892 | buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff); |
@@ -4054,7 +3955,8 @@ err: | |||
4054 | * | 3955 | * |
4055 | * See spc4r17 section 6.13.4 Table 165 | 3956 | * See spc4r17 section 6.13.4 Table 165 |
4056 | */ | 3957 | */ |
4057 | static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) | 3958 | static sense_reason_t |
3959 | core_scsi3_pri_report_capabilities(struct se_cmd *cmd) | ||
4058 | { | 3960 | { |
4059 | struct se_device *dev = cmd->se_dev; | 3961 | struct se_device *dev = cmd->se_dev; |
4060 | struct t10_reservation *pr_tmpl = &dev->t10_pr; | 3962 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
@@ -4064,11 +3966,12 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) | |||
4064 | if (cmd->data_length < 6) { | 3966 | if (cmd->data_length < 6) { |
4065 | pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" | 3967 | pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" |
4066 | " %u too small\n", cmd->data_length); | 3968 | " %u too small\n", cmd->data_length); |
4067 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 3969 | return TCM_INVALID_CDB_FIELD; |
4068 | return -EINVAL; | ||
4069 | } | 3970 | } |
4070 | 3971 | ||
4071 | buf = transport_kmap_data_sg(cmd); | 3972 | buf = transport_kmap_data_sg(cmd); |
3973 | if (!buf) | ||
3974 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
4072 | 3975 | ||
4073 | buf[0] = ((add_len << 8) & 0xff); | 3976 | buf[0] = ((add_len << 8) & 0xff); |
4074 | buf[1] = (add_len & 0xff); | 3977 | buf[1] = (add_len & 0xff); |
@@ -4110,7 +4013,8 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) | |||
4110 | * | 4013 | * |
4111 | * See spc4r17 section 6.13.5 Table 168 and 169 | 4014 | * See spc4r17 section 6.13.5 Table 168 and 169 |
4112 | */ | 4015 | */ |
4113 | static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | 4016 | static sense_reason_t |
4017 | core_scsi3_pri_read_full_status(struct se_cmd *cmd) | ||
4114 | { | 4018 | { |
4115 | struct se_device *dev = cmd->se_dev; | 4019 | struct se_device *dev = cmd->se_dev; |
4116 | struct se_node_acl *se_nacl; | 4020 | struct se_node_acl *se_nacl; |
@@ -4125,11 +4029,12 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | |||
4125 | if (cmd->data_length < 8) { | 4029 | if (cmd->data_length < 8) { |
4126 | pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" | 4030 | pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" |
4127 | " too small\n", cmd->data_length); | 4031 | " too small\n", cmd->data_length); |
4128 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 4032 | return TCM_INVALID_CDB_FIELD; |
4129 | return -EINVAL; | ||
4130 | } | 4033 | } |
4131 | 4034 | ||
4132 | buf = transport_kmap_data_sg(cmd); | 4035 | buf = transport_kmap_data_sg(cmd); |
4036 | if (!buf) | ||
4037 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
4133 | 4038 | ||
4134 | buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); | 4039 | buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff); |
4135 | buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); | 4040 | buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff); |
@@ -4255,9 +4160,10 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | |||
4255 | return 0; | 4160 | return 0; |
4256 | } | 4161 | } |
4257 | 4162 | ||
4258 | int target_scsi3_emulate_pr_in(struct se_cmd *cmd) | 4163 | sense_reason_t |
4164 | target_scsi3_emulate_pr_in(struct se_cmd *cmd) | ||
4259 | { | 4165 | { |
4260 | int ret; | 4166 | sense_reason_t ret; |
4261 | 4167 | ||
4262 | /* | 4168 | /* |
4263 | * Following spc2r20 5.5.1 Reservations overview: | 4169 | * Following spc2r20 5.5.1 Reservations overview: |
@@ -4272,8 +4178,7 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd) | |||
4272 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" | 4178 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" |
4273 | " SPC-2 reservation is held, returning" | 4179 | " SPC-2 reservation is held, returning" |
4274 | " RESERVATION_CONFLICT\n"); | 4180 | " RESERVATION_CONFLICT\n"); |
4275 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 4181 | return TCM_RESERVATION_CONFLICT; |
4276 | return -EINVAL; | ||
4277 | } | 4182 | } |
4278 | 4183 | ||
4279 | switch (cmd->t_task_cdb[1] & 0x1f) { | 4184 | switch (cmd->t_task_cdb[1] & 0x1f) { |
@@ -4292,9 +4197,7 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd) | |||
4292 | default: | 4197 | default: |
4293 | pr_err("Unknown PERSISTENT_RESERVE_IN service" | 4198 | pr_err("Unknown PERSISTENT_RESERVE_IN service" |
4294 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); | 4199 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); |
4295 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 4200 | return TCM_INVALID_CDB_FIELD; |
4296 | ret = -EINVAL; | ||
4297 | break; | ||
4298 | } | 4201 | } |
4299 | 4202 | ||
4300 | if (!ret) | 4203 | if (!ret) |
@@ -4302,10 +4205,11 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd) | |||
4302 | return ret; | 4205 | return ret; |
4303 | } | 4206 | } |
4304 | 4207 | ||
4305 | int target_check_reservation(struct se_cmd *cmd) | 4208 | sense_reason_t |
4209 | target_check_reservation(struct se_cmd *cmd) | ||
4306 | { | 4210 | { |
4307 | struct se_device *dev = cmd->se_dev; | 4211 | struct se_device *dev = cmd->se_dev; |
4308 | int ret; | 4212 | sense_reason_t ret; |
4309 | 4213 | ||
4310 | if (!cmd->se_sess) | 4214 | if (!cmd->se_sess) |
4311 | return 0; | 4215 | return 0; |
diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h index 7616f2690ca0..b4a004247ab2 100644 --- a/drivers/target/target_core_pr.h +++ b/drivers/target/target_core_pr.h | |||
@@ -47,8 +47,8 @@ extern struct kmem_cache *t10_pr_reg_cache; | |||
47 | 47 | ||
48 | extern int core_pr_dump_initiator_port(struct t10_pr_registration *, | 48 | extern int core_pr_dump_initiator_port(struct t10_pr_registration *, |
49 | char *, u32); | 49 | char *, u32); |
50 | extern int target_scsi2_reservation_release(struct se_cmd *); | 50 | extern sense_reason_t target_scsi2_reservation_release(struct se_cmd *); |
51 | extern int target_scsi2_reservation_reserve(struct se_cmd *); | 51 | extern sense_reason_t target_scsi2_reservation_reserve(struct se_cmd *); |
52 | extern int core_scsi3_alloc_aptpl_registration( | 52 | extern int core_scsi3_alloc_aptpl_registration( |
53 | struct t10_reservation *, u64, | 53 | struct t10_reservation *, u64, |
54 | unsigned char *, unsigned char *, u32, | 54 | unsigned char *, unsigned char *, u32, |
@@ -61,8 +61,8 @@ extern void core_scsi3_free_pr_reg_from_nacl(struct se_device *, | |||
61 | extern void core_scsi3_free_all_registrations(struct se_device *); | 61 | extern void core_scsi3_free_all_registrations(struct se_device *); |
62 | extern unsigned char *core_scsi3_pr_dump_type(int); | 62 | extern unsigned char *core_scsi3_pr_dump_type(int); |
63 | 63 | ||
64 | extern int target_scsi3_emulate_pr_in(struct se_cmd *); | 64 | extern sense_reason_t target_scsi3_emulate_pr_in(struct se_cmd *); |
65 | extern int target_scsi3_emulate_pr_out(struct se_cmd *); | 65 | extern sense_reason_t target_scsi3_emulate_pr_out(struct se_cmd *); |
66 | extern int target_check_reservation(struct se_cmd *cmd); | 66 | extern sense_reason_t target_check_reservation(struct se_cmd *); |
67 | 67 | ||
68 | #endif /* TARGET_CORE_PR_H */ | 68 | #endif /* TARGET_CORE_PR_H */ |
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index aa3e80a2f8db..b5c722bdd993 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -60,7 +60,7 @@ static inline struct pscsi_dev_virt *PSCSI_DEV(struct se_device *dev) | |||
60 | 60 | ||
61 | static struct se_subsystem_api pscsi_template; | 61 | static struct se_subsystem_api pscsi_template; |
62 | 62 | ||
63 | static int pscsi_execute_cmd(struct se_cmd *cmd); | 63 | static sense_reason_t pscsi_execute_cmd(struct se_cmd *cmd); |
64 | static void pscsi_req_done(struct request *, int); | 64 | static void pscsi_req_done(struct request *, int); |
65 | 65 | ||
66 | /* pscsi_attach_hba(): | 66 | /* pscsi_attach_hba(): |
@@ -642,7 +642,11 @@ static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg, | |||
642 | if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && | 642 | if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && |
643 | (status_byte(result) << 1) == SAM_STAT_GOOD) { | 643 | (status_byte(result) << 1) == SAM_STAT_GOOD) { |
644 | if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { | 644 | if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { |
645 | unsigned char *buf = transport_kmap_data_sg(cmd); | 645 | unsigned char *buf; |
646 | |||
647 | buf = transport_kmap_data_sg(cmd); | ||
648 | if (!buf) | ||
649 | ; /* XXX: TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE */ | ||
646 | 650 | ||
647 | if (cdb[0] == MODE_SENSE_10) { | 651 | if (cdb[0] == MODE_SENSE_10) { |
648 | if (!(buf[3] & 0x80)) | 652 | if (!(buf[3] & 0x80)) |
@@ -856,9 +860,9 @@ static inline struct bio *pscsi_get_bio(int sg_num) | |||
856 | return bio; | 860 | return bio; |
857 | } | 861 | } |
858 | 862 | ||
859 | static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, | 863 | static sense_reason_t |
860 | u32 sgl_nents, enum dma_data_direction data_direction, | 864 | pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, |
861 | struct bio **hbio) | 865 | enum dma_data_direction data_direction, struct bio **hbio) |
862 | { | 866 | { |
863 | struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev); | 867 | struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev); |
864 | struct bio *bio = NULL, *tbio = NULL; | 868 | struct bio *bio = NULL, *tbio = NULL; |
@@ -946,7 +950,7 @@ static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, | |||
946 | } | 950 | } |
947 | } | 951 | } |
948 | 952 | ||
949 | return sgl_nents; | 953 | return 0; |
950 | fail: | 954 | fail: |
951 | while (*hbio) { | 955 | while (*hbio) { |
952 | bio = *hbio; | 956 | bio = *hbio; |
@@ -954,8 +958,7 @@ fail: | |||
954 | bio->bi_next = NULL; | 958 | bio->bi_next = NULL; |
955 | bio_endio(bio, 0); /* XXX: should be error */ | 959 | bio_endio(bio, 0); /* XXX: should be error */ |
956 | } | 960 | } |
957 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 961 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
958 | return -ENOMEM; | ||
959 | } | 962 | } |
960 | 963 | ||
961 | /* | 964 | /* |
@@ -982,15 +985,13 @@ static inline void pscsi_clear_cdb_lun(unsigned char *cdb) | |||
982 | } | 985 | } |
983 | } | 986 | } |
984 | 987 | ||
985 | static int pscsi_parse_cdb(struct se_cmd *cmd) | 988 | static sense_reason_t |
989 | pscsi_parse_cdb(struct se_cmd *cmd) | ||
986 | { | 990 | { |
987 | unsigned char *cdb = cmd->t_task_cdb; | 991 | unsigned char *cdb = cmd->t_task_cdb; |
988 | 992 | ||
989 | if (cmd->se_cmd_flags & SCF_BIDI) { | 993 | if (cmd->se_cmd_flags & SCF_BIDI) |
990 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 994 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
991 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | ||
992 | return -EINVAL; | ||
993 | } | ||
994 | 995 | ||
995 | pscsi_clear_cdb_lun(cdb); | 996 | pscsi_clear_cdb_lun(cdb); |
996 | 997 | ||
@@ -1020,7 +1021,8 @@ static int pscsi_parse_cdb(struct se_cmd *cmd) | |||
1020 | } | 1021 | } |
1021 | } | 1022 | } |
1022 | 1023 | ||
1023 | static int pscsi_execute_cmd(struct se_cmd *cmd) | 1024 | static sense_reason_t |
1025 | pscsi_execute_cmd(struct se_cmd *cmd) | ||
1024 | { | 1026 | { |
1025 | struct scatterlist *sgl = cmd->t_data_sg; | 1027 | struct scatterlist *sgl = cmd->t_data_sg; |
1026 | u32 sgl_nents = cmd->t_data_nents; | 1028 | u32 sgl_nents = cmd->t_data_nents; |
@@ -1029,7 +1031,7 @@ static int pscsi_execute_cmd(struct se_cmd *cmd) | |||
1029 | struct pscsi_plugin_task *pt; | 1031 | struct pscsi_plugin_task *pt; |
1030 | struct request *req; | 1032 | struct request *req; |
1031 | struct bio *hbio; | 1033 | struct bio *hbio; |
1032 | int ret; | 1034 | sense_reason_t ret; |
1033 | 1035 | ||
1034 | /* | 1036 | /* |
1035 | * Dynamically alloc cdb space, since it may be larger than | 1037 | * Dynamically alloc cdb space, since it may be larger than |
@@ -1037,8 +1039,7 @@ static int pscsi_execute_cmd(struct se_cmd *cmd) | |||
1037 | */ | 1039 | */ |
1038 | pt = kzalloc(sizeof(*pt) + scsi_command_size(cmd->t_task_cdb), GFP_KERNEL); | 1040 | pt = kzalloc(sizeof(*pt) + scsi_command_size(cmd->t_task_cdb), GFP_KERNEL); |
1039 | if (!pt) { | 1041 | if (!pt) { |
1040 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1042 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1041 | return -ENOMEM; | ||
1042 | } | 1043 | } |
1043 | cmd->priv = pt; | 1044 | cmd->priv = pt; |
1044 | 1045 | ||
@@ -1052,24 +1053,21 @@ static int pscsi_execute_cmd(struct se_cmd *cmd) | |||
1052 | if (!req || IS_ERR(req)) { | 1053 | if (!req || IS_ERR(req)) { |
1053 | pr_err("PSCSI: blk_get_request() failed: %ld\n", | 1054 | pr_err("PSCSI: blk_get_request() failed: %ld\n", |
1054 | req ? IS_ERR(req) : -ENOMEM); | 1055 | req ? IS_ERR(req) : -ENOMEM); |
1055 | cmd->scsi_sense_reason = | 1056 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1056 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1057 | goto fail; | 1057 | goto fail; |
1058 | } | 1058 | } |
1059 | } else { | 1059 | } else { |
1060 | BUG_ON(!cmd->data_length); | 1060 | BUG_ON(!cmd->data_length); |
1061 | 1061 | ||
1062 | ret = pscsi_map_sg(cmd, sgl, sgl_nents, data_direction, &hbio); | 1062 | ret = pscsi_map_sg(cmd, sgl, sgl_nents, data_direction, &hbio); |
1063 | if (ret < 0) { | 1063 | if (ret) |
1064 | cmd->scsi_sense_reason = | ||
1065 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1066 | goto fail; | 1064 | goto fail; |
1067 | } | ||
1068 | 1065 | ||
1069 | req = blk_make_request(pdv->pdv_sd->request_queue, hbio, | 1066 | req = blk_make_request(pdv->pdv_sd->request_queue, hbio, |
1070 | GFP_KERNEL); | 1067 | GFP_KERNEL); |
1071 | if (IS_ERR(req)) { | 1068 | if (IS_ERR(req)) { |
1072 | pr_err("pSCSI: blk_make_request() failed\n"); | 1069 | pr_err("pSCSI: blk_make_request() failed\n"); |
1070 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1073 | goto fail_free_bio; | 1071 | goto fail_free_bio; |
1074 | } | 1072 | } |
1075 | } | 1073 | } |
@@ -1100,10 +1098,10 @@ fail_free_bio: | |||
1100 | bio->bi_next = NULL; | 1098 | bio->bi_next = NULL; |
1101 | bio_endio(bio, 0); /* XXX: should be error */ | 1099 | bio_endio(bio, 0); /* XXX: should be error */ |
1102 | } | 1100 | } |
1103 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1101 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1104 | fail: | 1102 | fail: |
1105 | kfree(pt); | 1103 | kfree(pt); |
1106 | return -ENOMEM; | 1104 | return ret; |
1107 | } | 1105 | } |
1108 | 1106 | ||
1109 | /* pscsi_get_device_type(): | 1107 | /* pscsi_get_device_type(): |
@@ -1152,7 +1150,6 @@ static void pscsi_req_done(struct request *req, int uptodate) | |||
1152 | pr_debug("PSCSI Host Byte exception at cmd: %p CDB:" | 1150 | pr_debug("PSCSI Host Byte exception at cmd: %p CDB:" |
1153 | " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0], | 1151 | " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0], |
1154 | pt->pscsi_result); | 1152 | pt->pscsi_result); |
1155 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | ||
1156 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); | 1153 | target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); |
1157 | break; | 1154 | break; |
1158 | } | 1155 | } |
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 92b1307a9931..126529cd5325 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c | |||
@@ -275,7 +275,8 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page) | |||
275 | return NULL; | 275 | return NULL; |
276 | } | 276 | } |
277 | 277 | ||
278 | static int rd_execute_rw(struct se_cmd *cmd) | 278 | static sense_reason_t |
279 | rd_execute_rw(struct se_cmd *cmd) | ||
279 | { | 280 | { |
280 | struct scatterlist *sgl = cmd->t_data_sg; | 281 | struct scatterlist *sgl = cmd->t_data_sg; |
281 | u32 sgl_nents = cmd->t_data_nents; | 282 | u32 sgl_nents = cmd->t_data_nents; |
@@ -298,7 +299,7 @@ static int rd_execute_rw(struct se_cmd *cmd) | |||
298 | 299 | ||
299 | table = rd_get_sg_table(dev, rd_page); | 300 | table = rd_get_sg_table(dev, rd_page); |
300 | if (!table) | 301 | if (!table) |
301 | return -EINVAL; | 302 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
302 | 303 | ||
303 | rd_sg = &table->sg_table[rd_page - table->page_start_offset]; | 304 | rd_sg = &table->sg_table[rd_page - table->page_start_offset]; |
304 | 305 | ||
@@ -348,7 +349,7 @@ static int rd_execute_rw(struct se_cmd *cmd) | |||
348 | table = rd_get_sg_table(dev, rd_page); | 349 | table = rd_get_sg_table(dev, rd_page); |
349 | if (!table) { | 350 | if (!table) { |
350 | sg_miter_stop(&m); | 351 | sg_miter_stop(&m); |
351 | return -EINVAL; | 352 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
352 | } | 353 | } |
353 | 354 | ||
354 | /* since we increment, the first sg entry is correct */ | 355 | /* since we increment, the first sg entry is correct */ |
@@ -431,7 +432,8 @@ static struct sbc_ops rd_sbc_ops = { | |||
431 | .execute_rw = rd_execute_rw, | 432 | .execute_rw = rd_execute_rw, |
432 | }; | 433 | }; |
433 | 434 | ||
434 | static int rd_parse_cdb(struct se_cmd *cmd) | 435 | static sense_reason_t |
436 | rd_parse_cdb(struct se_cmd *cmd) | ||
435 | { | 437 | { |
436 | return sbc_parse_cdb(cmd, &rd_sbc_ops); | 438 | return sbc_parse_cdb(cmd, &rd_sbc_ops); |
437 | } | 439 | } |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index a4eb9c553654..3929fa201088 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -37,7 +37,8 @@ | |||
37 | #include "target_core_ua.h" | 37 | #include "target_core_ua.h" |
38 | 38 | ||
39 | 39 | ||
40 | static int sbc_emulate_readcapacity(struct se_cmd *cmd) | 40 | static sense_reason_t |
41 | sbc_emulate_readcapacity(struct se_cmd *cmd) | ||
41 | { | 42 | { |
42 | struct se_device *dev = cmd->se_dev; | 43 | struct se_device *dev = cmd->se_dev; |
43 | unsigned long long blocks_long = dev->transport->get_blocks(dev); | 44 | unsigned long long blocks_long = dev->transport->get_blocks(dev); |
@@ -60,16 +61,18 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) | |||
60 | buf[7] = dev->dev_attrib.block_size & 0xff; | 61 | buf[7] = dev->dev_attrib.block_size & 0xff; |
61 | 62 | ||
62 | rbuf = transport_kmap_data_sg(cmd); | 63 | rbuf = transport_kmap_data_sg(cmd); |
63 | if (rbuf) { | 64 | if (!rbuf) |
64 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 65 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
65 | transport_kunmap_data_sg(cmd); | 66 | |
66 | } | 67 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
68 | transport_kunmap_data_sg(cmd); | ||
67 | 69 | ||
68 | target_complete_cmd(cmd, GOOD); | 70 | target_complete_cmd(cmd, GOOD); |
69 | return 0; | 71 | return 0; |
70 | } | 72 | } |
71 | 73 | ||
72 | static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) | 74 | static sense_reason_t |
75 | sbc_emulate_readcapacity_16(struct se_cmd *cmd) | ||
73 | { | 76 | { |
74 | struct se_device *dev = cmd->se_dev; | 77 | struct se_device *dev = cmd->se_dev; |
75 | unsigned char *rbuf; | 78 | unsigned char *rbuf; |
@@ -97,10 +100,11 @@ static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) | |||
97 | buf[14] = 0x80; | 100 | buf[14] = 0x80; |
98 | 101 | ||
99 | rbuf = transport_kmap_data_sg(cmd); | 102 | rbuf = transport_kmap_data_sg(cmd); |
100 | if (rbuf) { | 103 | if (!rbuf) |
101 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 104 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
102 | transport_kunmap_data_sg(cmd); | 105 | |
103 | } | 106 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
107 | transport_kunmap_data_sg(cmd); | ||
104 | 108 | ||
105 | target_complete_cmd(cmd, GOOD); | 109 | target_complete_cmd(cmd, GOOD); |
106 | return 0; | 110 | return 0; |
@@ -129,7 +133,8 @@ int spc_get_write_same_sectors(struct se_cmd *cmd) | |||
129 | } | 133 | } |
130 | EXPORT_SYMBOL(spc_get_write_same_sectors); | 134 | EXPORT_SYMBOL(spc_get_write_same_sectors); |
131 | 135 | ||
132 | static int sbc_emulate_verify(struct se_cmd *cmd) | 136 | static sense_reason_t |
137 | sbc_emulate_verify(struct se_cmd *cmd) | ||
133 | { | 138 | { |
134 | target_complete_cmd(cmd, GOOD); | 139 | target_complete_cmd(cmd, GOOD); |
135 | return 0; | 140 | return 0; |
@@ -313,13 +318,14 @@ out: | |||
313 | kfree(buf); | 318 | kfree(buf); |
314 | } | 319 | } |
315 | 320 | ||
316 | int sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | 321 | sense_reason_t |
322 | sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | ||
317 | { | 323 | { |
318 | struct se_device *dev = cmd->se_dev; | 324 | struct se_device *dev = cmd->se_dev; |
319 | unsigned char *cdb = cmd->t_task_cdb; | 325 | unsigned char *cdb = cmd->t_task_cdb; |
320 | unsigned int size; | 326 | unsigned int size; |
321 | u32 sectors = 0; | 327 | u32 sectors = 0; |
322 | int ret; | 328 | sense_reason_t ret; |
323 | 329 | ||
324 | switch (cdb[0]) { | 330 | switch (cdb[0]) { |
325 | case READ_6: | 331 | case READ_6: |
@@ -378,9 +384,9 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
378 | cmd->execute_cmd = ops->execute_rw; | 384 | cmd->execute_cmd = ops->execute_rw; |
379 | break; | 385 | break; |
380 | case XDWRITEREAD_10: | 386 | case XDWRITEREAD_10: |
381 | if ((cmd->data_direction != DMA_TO_DEVICE) || | 387 | if (cmd->data_direction != DMA_TO_DEVICE || |
382 | !(cmd->se_cmd_flags & SCF_BIDI)) | 388 | !(cmd->se_cmd_flags & SCF_BIDI)) |
383 | goto out_invalid_cdb_field; | 389 | return TCM_INVALID_CDB_FIELD; |
384 | sectors = transport_get_sectors_10(cdb); | 390 | sectors = transport_get_sectors_10(cdb); |
385 | 391 | ||
386 | cmd->t_task_lba = transport_lba_32(cdb); | 392 | cmd->t_task_lba = transport_lba_32(cdb); |
@@ -419,26 +425,26 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
419 | break; | 425 | break; |
420 | case WRITE_SAME_32: | 426 | case WRITE_SAME_32: |
421 | if (!ops->execute_write_same) | 427 | if (!ops->execute_write_same) |
422 | goto out_unsupported_cdb; | 428 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
423 | 429 | ||
424 | sectors = transport_get_sectors_32(cdb); | 430 | sectors = transport_get_sectors_32(cdb); |
425 | if (!sectors) { | 431 | if (!sectors) { |
426 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not" | 432 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not" |
427 | " supported\n"); | 433 | " supported\n"); |
428 | goto out_invalid_cdb_field; | 434 | return TCM_INVALID_CDB_FIELD; |
429 | } | 435 | } |
430 | 436 | ||
431 | size = sbc_get_size(cmd, 1); | 437 | size = sbc_get_size(cmd, 1); |
432 | cmd->t_task_lba = get_unaligned_be64(&cdb[12]); | 438 | cmd->t_task_lba = get_unaligned_be64(&cdb[12]); |
433 | 439 | ||
434 | if (sbc_write_same_supported(dev, &cdb[10]) < 0) | 440 | if (sbc_write_same_supported(dev, &cdb[10]) < 0) |
435 | goto out_unsupported_cdb; | 441 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
436 | cmd->execute_cmd = ops->execute_write_same; | 442 | cmd->execute_cmd = ops->execute_write_same; |
437 | break; | 443 | break; |
438 | default: | 444 | default: |
439 | pr_err("VARIABLE_LENGTH_CMD service action" | 445 | pr_err("VARIABLE_LENGTH_CMD service action" |
440 | " 0x%04x not supported\n", service_action); | 446 | " 0x%04x not supported\n", service_action); |
441 | goto out_unsupported_cdb; | 447 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
442 | } | 448 | } |
443 | break; | 449 | break; |
444 | } | 450 | } |
@@ -454,7 +460,7 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
454 | default: | 460 | default: |
455 | pr_err("Unsupported SA: 0x%02x\n", | 461 | pr_err("Unsupported SA: 0x%02x\n", |
456 | cmd->t_task_cdb[1] & 0x1f); | 462 | cmd->t_task_cdb[1] & 0x1f); |
457 | goto out_invalid_cdb_field; | 463 | return TCM_INVALID_CDB_FIELD; |
458 | } | 464 | } |
459 | size = (cdb[10] << 24) | (cdb[11] << 16) | | 465 | size = (cdb[10] << 24) | (cdb[11] << 16) | |
460 | (cdb[12] << 8) | cdb[13]; | 466 | (cdb[12] << 8) | cdb[13]; |
@@ -462,7 +468,7 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
462 | case SYNCHRONIZE_CACHE: | 468 | case SYNCHRONIZE_CACHE: |
463 | case SYNCHRONIZE_CACHE_16: | 469 | case SYNCHRONIZE_CACHE_16: |
464 | if (!ops->execute_sync_cache) | 470 | if (!ops->execute_sync_cache) |
465 | goto out_unsupported_cdb; | 471 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
466 | 472 | ||
467 | /* | 473 | /* |
468 | * Extract LBA and range to be flushed for emulated SYNCHRONIZE_CACHE | 474 | * Extract LBA and range to be flushed for emulated SYNCHRONIZE_CACHE |
@@ -483,42 +489,42 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
483 | */ | 489 | */ |
484 | if (cmd->t_task_lba || sectors) { | 490 | if (cmd->t_task_lba || sectors) { |
485 | if (sbc_check_valid_sectors(cmd) < 0) | 491 | if (sbc_check_valid_sectors(cmd) < 0) |
486 | goto out_invalid_cdb_field; | 492 | return TCM_INVALID_CDB_FIELD; |
487 | } | 493 | } |
488 | cmd->execute_cmd = ops->execute_sync_cache; | 494 | cmd->execute_cmd = ops->execute_sync_cache; |
489 | break; | 495 | break; |
490 | case UNMAP: | 496 | case UNMAP: |
491 | if (!ops->execute_unmap) | 497 | if (!ops->execute_unmap) |
492 | goto out_unsupported_cdb; | 498 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
493 | 499 | ||
494 | size = get_unaligned_be16(&cdb[7]); | 500 | size = get_unaligned_be16(&cdb[7]); |
495 | cmd->execute_cmd = ops->execute_unmap; | 501 | cmd->execute_cmd = ops->execute_unmap; |
496 | break; | 502 | break; |
497 | case WRITE_SAME_16: | 503 | case WRITE_SAME_16: |
498 | if (!ops->execute_write_same) | 504 | if (!ops->execute_write_same) |
499 | goto out_unsupported_cdb; | 505 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
500 | 506 | ||
501 | sectors = transport_get_sectors_16(cdb); | 507 | sectors = transport_get_sectors_16(cdb); |
502 | if (!sectors) { | 508 | if (!sectors) { |
503 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); | 509 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); |
504 | goto out_invalid_cdb_field; | 510 | return TCM_INVALID_CDB_FIELD; |
505 | } | 511 | } |
506 | 512 | ||
507 | size = sbc_get_size(cmd, 1); | 513 | size = sbc_get_size(cmd, 1); |
508 | cmd->t_task_lba = get_unaligned_be64(&cdb[2]); | 514 | cmd->t_task_lba = get_unaligned_be64(&cdb[2]); |
509 | 515 | ||
510 | if (sbc_write_same_supported(dev, &cdb[1]) < 0) | 516 | if (sbc_write_same_supported(dev, &cdb[1]) < 0) |
511 | goto out_unsupported_cdb; | 517 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
512 | cmd->execute_cmd = ops->execute_write_same; | 518 | cmd->execute_cmd = ops->execute_write_same; |
513 | break; | 519 | break; |
514 | case WRITE_SAME: | 520 | case WRITE_SAME: |
515 | if (!ops->execute_write_same) | 521 | if (!ops->execute_write_same) |
516 | goto out_unsupported_cdb; | 522 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
517 | 523 | ||
518 | sectors = transport_get_sectors_10(cdb); | 524 | sectors = transport_get_sectors_10(cdb); |
519 | if (!sectors) { | 525 | if (!sectors) { |
520 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); | 526 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); |
521 | goto out_invalid_cdb_field; | 527 | return TCM_INVALID_CDB_FIELD; |
522 | } | 528 | } |
523 | 529 | ||
524 | size = sbc_get_size(cmd, 1); | 530 | size = sbc_get_size(cmd, 1); |
@@ -529,7 +535,7 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
529 | * of byte 1 bit 3 UNMAP instead of original reserved field | 535 | * of byte 1 bit 3 UNMAP instead of original reserved field |
530 | */ | 536 | */ |
531 | if (sbc_write_same_supported(dev, &cdb[1]) < 0) | 537 | if (sbc_write_same_supported(dev, &cdb[1]) < 0) |
532 | goto out_unsupported_cdb; | 538 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
533 | cmd->execute_cmd = ops->execute_write_same; | 539 | cmd->execute_cmd = ops->execute_write_same; |
534 | break; | 540 | break; |
535 | case VERIFY: | 541 | case VERIFY: |
@@ -556,7 +562,7 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
556 | 562 | ||
557 | /* reject any command that we don't have a handler for */ | 563 | /* reject any command that we don't have a handler for */ |
558 | if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && !cmd->execute_cmd) | 564 | if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && !cmd->execute_cmd) |
559 | goto out_unsupported_cdb; | 565 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
560 | 566 | ||
561 | if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { | 567 | if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { |
562 | unsigned long long end_lba; | 568 | unsigned long long end_lba; |
@@ -566,14 +572,14 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
566 | " big sectors %u exceeds fabric_max_sectors:" | 572 | " big sectors %u exceeds fabric_max_sectors:" |
567 | " %u\n", cdb[0], sectors, | 573 | " %u\n", cdb[0], sectors, |
568 | dev->dev_attrib.fabric_max_sectors); | 574 | dev->dev_attrib.fabric_max_sectors); |
569 | goto out_invalid_cdb_field; | 575 | return TCM_INVALID_CDB_FIELD; |
570 | } | 576 | } |
571 | if (sectors > dev->dev_attrib.hw_max_sectors) { | 577 | if (sectors > dev->dev_attrib.hw_max_sectors) { |
572 | printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" | 578 | printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" |
573 | " big sectors %u exceeds backend hw_max_sectors:" | 579 | " big sectors %u exceeds backend hw_max_sectors:" |
574 | " %u\n", cdb[0], sectors, | 580 | " %u\n", cdb[0], sectors, |
575 | dev->dev_attrib.hw_max_sectors); | 581 | dev->dev_attrib.hw_max_sectors); |
576 | goto out_invalid_cdb_field; | 582 | return TCM_INVALID_CDB_FIELD; |
577 | } | 583 | } |
578 | 584 | ||
579 | end_lba = dev->transport->get_blocks(dev) + 1; | 585 | end_lba = dev->transport->get_blocks(dev) + 1; |
@@ -581,26 +587,13 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
581 | pr_err("cmd exceeds last lba %llu " | 587 | pr_err("cmd exceeds last lba %llu " |
582 | "(lba %llu, sectors %u)\n", | 588 | "(lba %llu, sectors %u)\n", |
583 | end_lba, cmd->t_task_lba, sectors); | 589 | end_lba, cmd->t_task_lba, sectors); |
584 | goto out_invalid_cdb_field; | 590 | return TCM_INVALID_CDB_FIELD; |
585 | } | 591 | } |
586 | 592 | ||
587 | size = sbc_get_size(cmd, sectors); | 593 | size = sbc_get_size(cmd, sectors); |
588 | } | 594 | } |
589 | 595 | ||
590 | ret = target_cmd_size_check(cmd, size); | 596 | return target_cmd_size_check(cmd, size); |
591 | if (ret < 0) | ||
592 | return ret; | ||
593 | |||
594 | return 0; | ||
595 | |||
596 | out_unsupported_cdb: | ||
597 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
598 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | ||
599 | return -EINVAL; | ||
600 | out_invalid_cdb_field: | ||
601 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
602 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
603 | return -EINVAL; | ||
604 | } | 597 | } |
605 | EXPORT_SYMBOL(sbc_parse_cdb); | 598 | EXPORT_SYMBOL(sbc_parse_cdb); |
606 | 599 | ||
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index f9c2bd02043c..4b3c18305ec8 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -69,7 +69,8 @@ static void spc_fill_alua_data(struct se_port *port, unsigned char *buf) | |||
69 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 69 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
70 | } | 70 | } |
71 | 71 | ||
72 | static int spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf) | 72 | static sense_reason_t |
73 | spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf) | ||
73 | { | 74 | { |
74 | struct se_lun *lun = cmd->se_lun; | 75 | struct se_lun *lun = cmd->se_lun; |
75 | struct se_device *dev = cmd->se_dev; | 76 | struct se_device *dev = cmd->se_dev; |
@@ -108,7 +109,8 @@ static int spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf) | |||
108 | } | 109 | } |
109 | 110 | ||
110 | /* unit serial number */ | 111 | /* unit serial number */ |
111 | static int spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) | 112 | static sense_reason_t |
113 | spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) | ||
112 | { | 114 | { |
113 | struct se_device *dev = cmd->se_dev; | 115 | struct se_device *dev = cmd->se_dev; |
114 | u16 len = 0; | 116 | u16 len = 0; |
@@ -161,7 +163,8 @@ static void spc_parse_naa_6h_vendor_specific(struct se_device *dev, | |||
161 | * Device identification VPD, for a complete list of | 163 | * Device identification VPD, for a complete list of |
162 | * DESIGNATOR TYPEs see spc4r17 Table 459. | 164 | * DESIGNATOR TYPEs see spc4r17 Table 459. |
163 | */ | 165 | */ |
164 | static int spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) | 166 | static sense_reason_t |
167 | spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) | ||
165 | { | 168 | { |
166 | struct se_device *dev = cmd->se_dev; | 169 | struct se_device *dev = cmd->se_dev; |
167 | struct se_lun *lun = cmd->se_lun; | 170 | struct se_lun *lun = cmd->se_lun; |
@@ -406,7 +409,8 @@ check_scsi_name: | |||
406 | } | 409 | } |
407 | 410 | ||
408 | /* Extended INQUIRY Data VPD Page */ | 411 | /* Extended INQUIRY Data VPD Page */ |
409 | static int spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) | 412 | static sense_reason_t |
413 | spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) | ||
410 | { | 414 | { |
411 | buf[3] = 0x3c; | 415 | buf[3] = 0x3c; |
412 | /* Set HEADSUP, ORDSUP, SIMPSUP */ | 416 | /* Set HEADSUP, ORDSUP, SIMPSUP */ |
@@ -419,7 +423,8 @@ static int spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) | |||
419 | } | 423 | } |
420 | 424 | ||
421 | /* Block Limits VPD page */ | 425 | /* Block Limits VPD page */ |
422 | static int spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | 426 | static sense_reason_t |
427 | spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | ||
423 | { | 428 | { |
424 | struct se_device *dev = cmd->se_dev; | 429 | struct se_device *dev = cmd->se_dev; |
425 | u32 max_sectors; | 430 | u32 max_sectors; |
@@ -490,7 +495,8 @@ static int spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | |||
490 | } | 495 | } |
491 | 496 | ||
492 | /* Block Device Characteristics VPD page */ | 497 | /* Block Device Characteristics VPD page */ |
493 | static int spc_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf) | 498 | static sense_reason_t |
499 | spc_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf) | ||
494 | { | 500 | { |
495 | struct se_device *dev = cmd->se_dev; | 501 | struct se_device *dev = cmd->se_dev; |
496 | 502 | ||
@@ -502,7 +508,8 @@ static int spc_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf) | |||
502 | } | 508 | } |
503 | 509 | ||
504 | /* Thin Provisioning VPD */ | 510 | /* Thin Provisioning VPD */ |
505 | static int spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) | 511 | static sense_reason_t |
512 | spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) | ||
506 | { | 513 | { |
507 | struct se_device *dev = cmd->se_dev; | 514 | struct se_device *dev = cmd->se_dev; |
508 | 515 | ||
@@ -552,11 +559,12 @@ static int spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) | |||
552 | return 0; | 559 | return 0; |
553 | } | 560 | } |
554 | 561 | ||
555 | static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf); | 562 | static sense_reason_t |
563 | spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf); | ||
556 | 564 | ||
557 | static struct { | 565 | static struct { |
558 | uint8_t page; | 566 | uint8_t page; |
559 | int (*emulate)(struct se_cmd *, unsigned char *); | 567 | sense_reason_t (*emulate)(struct se_cmd *, unsigned char *); |
560 | } evpd_handlers[] = { | 568 | } evpd_handlers[] = { |
561 | { .page = 0x00, .emulate = spc_emulate_evpd_00 }, | 569 | { .page = 0x00, .emulate = spc_emulate_evpd_00 }, |
562 | { .page = 0x80, .emulate = spc_emulate_evpd_80 }, | 570 | { .page = 0x80, .emulate = spc_emulate_evpd_80 }, |
@@ -568,7 +576,8 @@ static struct { | |||
568 | }; | 576 | }; |
569 | 577 | ||
570 | /* supported vital product data pages */ | 578 | /* supported vital product data pages */ |
571 | static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) | 579 | static sense_reason_t |
580 | spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) | ||
572 | { | 581 | { |
573 | int p; | 582 | int p; |
574 | 583 | ||
@@ -586,14 +595,16 @@ static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) | |||
586 | return 0; | 595 | return 0; |
587 | } | 596 | } |
588 | 597 | ||
589 | static int spc_emulate_inquiry(struct se_cmd *cmd) | 598 | static sense_reason_t |
599 | spc_emulate_inquiry(struct se_cmd *cmd) | ||
590 | { | 600 | { |
591 | struct se_device *dev = cmd->se_dev; | 601 | struct se_device *dev = cmd->se_dev; |
592 | struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg; | 602 | struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg; |
593 | unsigned char *rbuf; | 603 | unsigned char *rbuf; |
594 | unsigned char *cdb = cmd->t_task_cdb; | 604 | unsigned char *cdb = cmd->t_task_cdb; |
595 | unsigned char buf[SE_INQUIRY_BUF]; | 605 | unsigned char buf[SE_INQUIRY_BUF]; |
596 | int p, ret; | 606 | sense_reason_t ret; |
607 | int p; | ||
597 | 608 | ||
598 | memset(buf, 0, SE_INQUIRY_BUF); | 609 | memset(buf, 0, SE_INQUIRY_BUF); |
599 | 610 | ||
@@ -606,8 +617,7 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) | |||
606 | if (cdb[2]) { | 617 | if (cdb[2]) { |
607 | pr_err("INQUIRY with EVPD==0 but PAGE CODE=%02x\n", | 618 | pr_err("INQUIRY with EVPD==0 but PAGE CODE=%02x\n", |
608 | cdb[2]); | 619 | cdb[2]); |
609 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 620 | ret = TCM_INVALID_CDB_FIELD; |
610 | ret = -EINVAL; | ||
611 | goto out; | 621 | goto out; |
612 | } | 622 | } |
613 | 623 | ||
@@ -624,15 +634,15 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) | |||
624 | } | 634 | } |
625 | 635 | ||
626 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); | 636 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); |
627 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 637 | ret = TCM_INVALID_CDB_FIELD; |
628 | ret = -EINVAL; | ||
629 | 638 | ||
630 | out: | 639 | out: |
631 | rbuf = transport_kmap_data_sg(cmd); | 640 | rbuf = transport_kmap_data_sg(cmd); |
632 | if (rbuf) { | 641 | if (!rbuf) |
633 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 642 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
634 | transport_kunmap_data_sg(cmd); | 643 | |
635 | } | 644 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
645 | transport_kunmap_data_sg(cmd); | ||
636 | 646 | ||
637 | if (!ret) | 647 | if (!ret) |
638 | target_complete_cmd(cmd, GOOD); | 648 | target_complete_cmd(cmd, GOOD); |
@@ -834,7 +844,7 @@ static int spc_modesense_long_blockdesc(unsigned char *buf, u64 blocks, u32 bloc | |||
834 | return 17; | 844 | return 17; |
835 | } | 845 | } |
836 | 846 | ||
837 | static int spc_emulate_modesense(struct se_cmd *cmd) | 847 | static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) |
838 | { | 848 | { |
839 | struct se_device *dev = cmd->se_dev; | 849 | struct se_device *dev = cmd->se_dev; |
840 | char *cdb = cmd->t_task_cdb; | 850 | char *cdb = cmd->t_task_cdb; |
@@ -851,7 +861,8 @@ static int spc_emulate_modesense(struct se_cmd *cmd) | |||
851 | int i; | 861 | int i; |
852 | 862 | ||
853 | map_buf = transport_kmap_data_sg(cmd); | 863 | map_buf = transport_kmap_data_sg(cmd); |
854 | 864 | if (!map_buf) | |
865 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
855 | /* | 866 | /* |
856 | * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we | 867 | * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we |
857 | * know we actually allocated a full page. Otherwise, if the | 868 | * know we actually allocated a full page. Otherwise, if the |
@@ -864,8 +875,7 @@ static int spc_emulate_modesense(struct se_cmd *cmd) | |||
864 | buf = kzalloc(SE_MODE_PAGE_BUF, GFP_KERNEL); | 875 | buf = kzalloc(SE_MODE_PAGE_BUF, GFP_KERNEL); |
865 | if (!buf) { | 876 | if (!buf) { |
866 | transport_kunmap_data_sg(cmd); | 877 | transport_kunmap_data_sg(cmd); |
867 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 878 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
868 | return -ENOMEM; | ||
869 | } | 879 | } |
870 | } else { | 880 | } else { |
871 | buf = map_buf; | 881 | buf = map_buf; |
@@ -920,9 +930,10 @@ static int spc_emulate_modesense(struct se_cmd *cmd) | |||
920 | 930 | ||
921 | if (page == 0x3f) { | 931 | if (page == 0x3f) { |
922 | if (subpage != 0x00 && subpage != 0xff) { | 932 | if (subpage != 0x00 && subpage != 0xff) { |
923 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 933 | pr_warn("MODE_SENSE: Invalid subpage code: 0x%02x\n", subpage); |
924 | length = -EINVAL; | 934 | kfree(buf); |
925 | goto out; | 935 | transport_kunmap_data_sg(cmd); |
936 | return TCM_INVALID_CDB_FIELD; | ||
926 | } | 937 | } |
927 | 938 | ||
928 | for (i = 0; i < ARRAY_SIZE(modesense_handlers); ++i) { | 939 | for (i = 0; i < ARRAY_SIZE(modesense_handlers); ++i) { |
@@ -958,8 +969,8 @@ static int spc_emulate_modesense(struct se_cmd *cmd) | |||
958 | pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", | 969 | pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", |
959 | page, subpage); | 970 | page, subpage); |
960 | 971 | ||
961 | cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE; | 972 | transport_kunmap_data_sg(cmd); |
962 | return -EINVAL; | 973 | return TCM_UNKNOWN_MODE_PAGE; |
963 | 974 | ||
964 | set_length: | 975 | set_length: |
965 | if (ten) | 976 | if (ten) |
@@ -967,7 +978,6 @@ set_length: | |||
967 | else | 978 | else |
968 | buf[0] = length - 1; | 979 | buf[0] = length - 1; |
969 | 980 | ||
970 | out: | ||
971 | if (buf != map_buf) { | 981 | if (buf != map_buf) { |
972 | memcpy(map_buf, buf, cmd->data_length); | 982 | memcpy(map_buf, buf, cmd->data_length); |
973 | kfree(buf); | 983 | kfree(buf); |
@@ -978,7 +988,7 @@ out: | |||
978 | return 0; | 988 | return 0; |
979 | } | 989 | } |
980 | 990 | ||
981 | static int spc_emulate_modeselect(struct se_cmd *cmd) | 991 | static sense_reason_t spc_emulate_modeselect(struct se_cmd *cmd) |
982 | { | 992 | { |
983 | struct se_device *dev = cmd->se_dev; | 993 | struct se_device *dev = cmd->se_dev; |
984 | char *cdb = cmd->t_task_cdb; | 994 | char *cdb = cmd->t_task_cdb; |
@@ -993,10 +1003,11 @@ static int spc_emulate_modeselect(struct se_cmd *cmd) | |||
993 | int i; | 1003 | int i; |
994 | 1004 | ||
995 | buf = transport_kmap_data_sg(cmd); | 1005 | buf = transport_kmap_data_sg(cmd); |
1006 | if (!buf) | ||
1007 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
996 | 1008 | ||
997 | if (!pf) { | 1009 | if (!pf) { |
998 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 1010 | ret = TCM_INVALID_CDB_FIELD; |
999 | ret = -EINVAL; | ||
1000 | goto out; | 1011 | goto out; |
1001 | } | 1012 | } |
1002 | 1013 | ||
@@ -1011,15 +1022,12 @@ static int spc_emulate_modeselect(struct se_cmd *cmd) | |||
1011 | goto check_contents; | 1022 | goto check_contents; |
1012 | } | 1023 | } |
1013 | 1024 | ||
1014 | cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE; | 1025 | ret = TCM_UNKNOWN_MODE_PAGE; |
1015 | ret = -EINVAL; | ||
1016 | goto out; | 1026 | goto out; |
1017 | 1027 | ||
1018 | check_contents: | 1028 | check_contents: |
1019 | if (memcmp(buf + off, tbuf, length)) { | 1029 | if (memcmp(buf + off, tbuf, length)) |
1020 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 1030 | ret = TCM_INVALID_PARAMETER_LIST; |
1021 | ret = -EINVAL; | ||
1022 | } | ||
1023 | 1031 | ||
1024 | out: | 1032 | out: |
1025 | transport_kunmap_data_sg(cmd); | 1033 | transport_kunmap_data_sg(cmd); |
@@ -1029,7 +1037,7 @@ out: | |||
1029 | return ret; | 1037 | return ret; |
1030 | } | 1038 | } |
1031 | 1039 | ||
1032 | static int spc_emulate_request_sense(struct se_cmd *cmd) | 1040 | static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd) |
1033 | { | 1041 | { |
1034 | unsigned char *cdb = cmd->t_task_cdb; | 1042 | unsigned char *cdb = cmd->t_task_cdb; |
1035 | unsigned char *rbuf; | 1043 | unsigned char *rbuf; |
@@ -1041,19 +1049,14 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
1041 | if (cdb[1] & 0x01) { | 1049 | if (cdb[1] & 0x01) { |
1042 | pr_err("REQUEST_SENSE description emulation not" | 1050 | pr_err("REQUEST_SENSE description emulation not" |
1043 | " supported\n"); | 1051 | " supported\n"); |
1044 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 1052 | return TCM_INVALID_CDB_FIELD; |
1045 | return -ENOSYS; | ||
1046 | } | 1053 | } |
1047 | 1054 | ||
1048 | rbuf = transport_kmap_data_sg(cmd); | 1055 | rbuf = transport_kmap_data_sg(cmd); |
1049 | if (cmd->scsi_sense_reason != 0) { | 1056 | if (!rbuf) |
1050 | /* | 1057 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1051 | * Out of memory. We will fail with CHECK CONDITION, so | 1058 | |
1052 | * we must not clear the unit attention condition. | 1059 | if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { |
1053 | */ | ||
1054 | target_complete_cmd(cmd, CHECK_CONDITION); | ||
1055 | return 0; | ||
1056 | } else if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { | ||
1057 | /* | 1060 | /* |
1058 | * CURRENT ERROR, UNIT ATTENTION | 1061 | * CURRENT ERROR, UNIT ATTENTION |
1059 | */ | 1062 | */ |
@@ -1080,16 +1083,14 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
1080 | buf[7] = 0x0A; | 1083 | buf[7] = 0x0A; |
1081 | } | 1084 | } |
1082 | 1085 | ||
1083 | if (rbuf) { | 1086 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
1084 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 1087 | transport_kunmap_data_sg(cmd); |
1085 | transport_kunmap_data_sg(cmd); | ||
1086 | } | ||
1087 | 1088 | ||
1088 | target_complete_cmd(cmd, GOOD); | 1089 | target_complete_cmd(cmd, GOOD); |
1089 | return 0; | 1090 | return 0; |
1090 | } | 1091 | } |
1091 | 1092 | ||
1092 | int spc_emulate_report_luns(struct se_cmd *cmd) | 1093 | sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) |
1093 | { | 1094 | { |
1094 | struct se_dev_entry *deve; | 1095 | struct se_dev_entry *deve; |
1095 | struct se_session *sess = cmd->se_sess; | 1096 | struct se_session *sess = cmd->se_sess; |
@@ -1099,13 +1100,12 @@ int spc_emulate_report_luns(struct se_cmd *cmd) | |||
1099 | if (cmd->data_length < 16) { | 1100 | if (cmd->data_length < 16) { |
1100 | pr_warn("REPORT LUNS allocation length %u too small\n", | 1101 | pr_warn("REPORT LUNS allocation length %u too small\n", |
1101 | cmd->data_length); | 1102 | cmd->data_length); |
1102 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 1103 | return TCM_INVALID_CDB_FIELD; |
1103 | return -EINVAL; | ||
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | buf = transport_kmap_data_sg(cmd); | 1106 | buf = transport_kmap_data_sg(cmd); |
1107 | if (!buf) | 1107 | if (!buf) |
1108 | return -ENOMEM; | 1108 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1109 | 1109 | ||
1110 | /* | 1110 | /* |
1111 | * If no struct se_session pointer is present, this struct se_cmd is | 1111 | * If no struct se_session pointer is present, this struct se_cmd is |
@@ -1153,13 +1153,15 @@ done: | |||
1153 | } | 1153 | } |
1154 | EXPORT_SYMBOL(spc_emulate_report_luns); | 1154 | EXPORT_SYMBOL(spc_emulate_report_luns); |
1155 | 1155 | ||
1156 | static int spc_emulate_testunitready(struct se_cmd *cmd) | 1156 | static sense_reason_t |
1157 | spc_emulate_testunitready(struct se_cmd *cmd) | ||
1157 | { | 1158 | { |
1158 | target_complete_cmd(cmd, GOOD); | 1159 | target_complete_cmd(cmd, GOOD); |
1159 | return 0; | 1160 | return 0; |
1160 | } | 1161 | } |
1161 | 1162 | ||
1162 | int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | 1163 | sense_reason_t |
1164 | spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | ||
1163 | { | 1165 | { |
1164 | struct se_device *dev = cmd->se_dev; | 1166 | struct se_device *dev = cmd->se_dev; |
1165 | unsigned char *cdb = cmd->t_task_cdb; | 1167 | unsigned char *cdb = cmd->t_task_cdb; |
@@ -1300,9 +1302,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
1300 | pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" | 1302 | pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" |
1301 | " 0x%02x, sending CHECK_CONDITION.\n", | 1303 | " 0x%02x, sending CHECK_CONDITION.\n", |
1302 | cmd->se_tfo->get_fabric_name(), cdb[0]); | 1304 | cmd->se_tfo->get_fabric_name(), cdb[0]); |
1303 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 1305 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
1304 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | ||
1305 | return -EINVAL; | ||
1306 | } | 1306 | } |
1307 | 1307 | ||
1308 | return 0; | 1308 | return 0; |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index c4c931b525d2..98044bf1da08 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -557,7 +557,8 @@ static void target_complete_failure_work(struct work_struct *work) | |||
557 | { | 557 | { |
558 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); | 558 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); |
559 | 559 | ||
560 | transport_generic_request_failure(cmd); | 560 | transport_generic_request_failure(cmd, |
561 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE); | ||
561 | } | 562 | } |
562 | 563 | ||
563 | /* | 564 | /* |
@@ -625,7 +626,6 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | |||
625 | complete(&cmd->t_transport_stop_comp); | 626 | complete(&cmd->t_transport_stop_comp); |
626 | return; | 627 | return; |
627 | } else if (cmd->transport_state & CMD_T_FAILED) { | 628 | } else if (cmd->transport_state & CMD_T_FAILED) { |
628 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
629 | INIT_WORK(&cmd->work, target_complete_failure_work); | 629 | INIT_WORK(&cmd->work, target_complete_failure_work); |
630 | } else { | 630 | } else { |
631 | INIT_WORK(&cmd->work, target_complete_ok_work); | 631 | INIT_WORK(&cmd->work, target_complete_ok_work); |
@@ -976,7 +976,8 @@ transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83) | |||
976 | } | 976 | } |
977 | EXPORT_SYMBOL(transport_set_vpd_ident); | 977 | EXPORT_SYMBOL(transport_set_vpd_ident); |
978 | 978 | ||
979 | int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | 979 | sense_reason_t |
980 | target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | ||
980 | { | 981 | { |
981 | struct se_device *dev = cmd->se_dev; | 982 | struct se_device *dev = cmd->se_dev; |
982 | 983 | ||
@@ -991,7 +992,7 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | |||
991 | if (cmd->data_direction == DMA_TO_DEVICE) { | 992 | if (cmd->data_direction == DMA_TO_DEVICE) { |
992 | pr_err("Rejecting underflow/overflow" | 993 | pr_err("Rejecting underflow/overflow" |
993 | " WRITE data\n"); | 994 | " WRITE data\n"); |
994 | goto out_invalid_cdb_field; | 995 | return TCM_INVALID_CDB_FIELD; |
995 | } | 996 | } |
996 | /* | 997 | /* |
997 | * Reject READ_* or WRITE_* with overflow/underflow for | 998 | * Reject READ_* or WRITE_* with overflow/underflow for |
@@ -1002,7 +1003,7 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | |||
1002 | " CDB on non 512-byte sector setup subsystem" | 1003 | " CDB on non 512-byte sector setup subsystem" |
1003 | " plugin: %s\n", dev->transport->name); | 1004 | " plugin: %s\n", dev->transport->name); |
1004 | /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ | 1005 | /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ |
1005 | goto out_invalid_cdb_field; | 1006 | return TCM_INVALID_CDB_FIELD; |
1006 | } | 1007 | } |
1007 | /* | 1008 | /* |
1008 | * For the overflow case keep the existing fabric provided | 1009 | * For the overflow case keep the existing fabric provided |
@@ -1022,10 +1023,6 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | |||
1022 | 1023 | ||
1023 | return 0; | 1024 | return 0; |
1024 | 1025 | ||
1025 | out_invalid_cdb_field: | ||
1026 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1027 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1028 | return -EINVAL; | ||
1029 | } | 1026 | } |
1030 | 1027 | ||
1031 | /* | 1028 | /* |
@@ -1065,7 +1062,8 @@ void transport_init_se_cmd( | |||
1065 | } | 1062 | } |
1066 | EXPORT_SYMBOL(transport_init_se_cmd); | 1063 | EXPORT_SYMBOL(transport_init_se_cmd); |
1067 | 1064 | ||
1068 | static int transport_check_alloc_task_attr(struct se_cmd *cmd) | 1065 | static sense_reason_t |
1066 | transport_check_alloc_task_attr(struct se_cmd *cmd) | ||
1069 | { | 1067 | { |
1070 | struct se_device *dev = cmd->se_dev; | 1068 | struct se_device *dev = cmd->se_dev; |
1071 | 1069 | ||
@@ -1079,7 +1077,7 @@ static int transport_check_alloc_task_attr(struct se_cmd *cmd) | |||
1079 | if (cmd->sam_task_attr == MSG_ACA_TAG) { | 1077 | if (cmd->sam_task_attr == MSG_ACA_TAG) { |
1080 | pr_debug("SAM Task Attribute ACA" | 1078 | pr_debug("SAM Task Attribute ACA" |
1081 | " emulation is not supported\n"); | 1079 | " emulation is not supported\n"); |
1082 | return -EINVAL; | 1080 | return TCM_INVALID_CDB_FIELD; |
1083 | } | 1081 | } |
1084 | /* | 1082 | /* |
1085 | * Used to determine when ORDERED commands should go from | 1083 | * Used to determine when ORDERED commands should go from |
@@ -1093,17 +1091,12 @@ static int transport_check_alloc_task_attr(struct se_cmd *cmd) | |||
1093 | return 0; | 1091 | return 0; |
1094 | } | 1092 | } |
1095 | 1093 | ||
1096 | /* target_setup_cmd_from_cdb(): | 1094 | sense_reason_t |
1097 | * | 1095 | target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb) |
1098 | * Called from fabric RX Thread. | ||
1099 | */ | ||
1100 | int target_setup_cmd_from_cdb( | ||
1101 | struct se_cmd *cmd, | ||
1102 | unsigned char *cdb) | ||
1103 | { | 1096 | { |
1104 | struct se_device *dev = cmd->se_dev; | 1097 | struct se_device *dev = cmd->se_dev; |
1105 | unsigned long flags; | 1098 | unsigned long flags; |
1106 | int ret; | 1099 | sense_reason_t ret; |
1107 | 1100 | ||
1108 | /* | 1101 | /* |
1109 | * Ensure that the received CDB is less than the max (252 + 8) bytes | 1102 | * Ensure that the received CDB is less than the max (252 + 8) bytes |
@@ -1113,9 +1106,7 @@ int target_setup_cmd_from_cdb( | |||
1113 | pr_err("Received SCSI CDB with command_size: %d that" | 1106 | pr_err("Received SCSI CDB with command_size: %d that" |
1114 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", | 1107 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", |
1115 | scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE); | 1108 | scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE); |
1116 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 1109 | return TCM_INVALID_CDB_FIELD; |
1117 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1118 | return -EINVAL; | ||
1119 | } | 1110 | } |
1120 | /* | 1111 | /* |
1121 | * If the received CDB is larger than TCM_MAX_COMMAND_SIZE, | 1112 | * If the received CDB is larger than TCM_MAX_COMMAND_SIZE, |
@@ -1130,10 +1121,7 @@ int target_setup_cmd_from_cdb( | |||
1130 | " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", | 1121 | " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", |
1131 | scsi_command_size(cdb), | 1122 | scsi_command_size(cdb), |
1132 | (unsigned long)sizeof(cmd->__t_task_cdb)); | 1123 | (unsigned long)sizeof(cmd->__t_task_cdb)); |
1133 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 1124 | return TCM_OUT_OF_RESOURCES; |
1134 | cmd->scsi_sense_reason = | ||
1135 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1136 | return -ENOMEM; | ||
1137 | } | 1125 | } |
1138 | } else | 1126 | } else |
1139 | cmd->t_task_cdb = &cmd->__t_task_cdb[0]; | 1127 | cmd->t_task_cdb = &cmd->__t_task_cdb[0]; |
@@ -1145,50 +1133,30 @@ int target_setup_cmd_from_cdb( | |||
1145 | /* | 1133 | /* |
1146 | * Check for an existing UNIT ATTENTION condition | 1134 | * Check for an existing UNIT ATTENTION condition |
1147 | */ | 1135 | */ |
1148 | if (core_scsi3_ua_check(cmd, cdb) < 0) { | 1136 | ret = target_scsi3_ua_check(cmd); |
1149 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 1137 | if (ret) |
1150 | cmd->scsi_sense_reason = TCM_CHECK_CONDITION_UNIT_ATTENTION; | 1138 | return ret; |
1151 | return -EINVAL; | ||
1152 | } | ||
1153 | 1139 | ||
1154 | ret = target_alua_state_check(cmd); | 1140 | ret = target_alua_state_check(cmd); |
1155 | if (ret) { | 1141 | if (ret) |
1156 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 1142 | return ret; |
1157 | if (ret > 0) | ||
1158 | cmd->scsi_sense_reason = TCM_CHECK_CONDITION_NOT_READY; | ||
1159 | else | ||
1160 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1161 | return -EINVAL; | ||
1162 | } | ||
1163 | 1143 | ||
1164 | /* | ||
1165 | * Check status for SPC-3 Persistent Reservations | ||
1166 | */ | ||
1167 | ret = target_check_reservation(cmd); | 1144 | ret = target_check_reservation(cmd); |
1168 | if (ret) { | 1145 | if (ret) |
1169 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1170 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; | ||
1171 | cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; | ||
1172 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
1173 | return ret; | 1146 | return ret; |
1174 | } | ||
1175 | 1147 | ||
1176 | ret = dev->transport->parse_cdb(cmd); | 1148 | ret = dev->transport->parse_cdb(cmd); |
1177 | if (ret < 0) | 1149 | if (ret) |
1150 | return ret; | ||
1151 | |||
1152 | ret = transport_check_alloc_task_attr(cmd); | ||
1153 | if (ret) | ||
1178 | return ret; | 1154 | return ret; |
1179 | 1155 | ||
1180 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 1156 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
1181 | cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE; | 1157 | cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE; |
1182 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 1158 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
1183 | 1159 | ||
1184 | /* | ||
1185 | * Check for SAM Task Attribute Emulation | ||
1186 | */ | ||
1187 | if (transport_check_alloc_task_attr(cmd) < 0) { | ||
1188 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1189 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1190 | return -EINVAL; | ||
1191 | } | ||
1192 | spin_lock(&cmd->se_lun->lun_sep_lock); | 1160 | spin_lock(&cmd->se_lun->lun_sep_lock); |
1193 | if (cmd->se_lun->lun_sep) | 1161 | if (cmd->se_lun->lun_sep) |
1194 | cmd->se_lun->lun_sep->sep_stats.cmd_pdus++; | 1162 | cmd->se_lun->lun_sep->sep_stats.cmd_pdus++; |
@@ -1204,7 +1172,7 @@ EXPORT_SYMBOL(target_setup_cmd_from_cdb); | |||
1204 | int transport_handle_cdb_direct( | 1172 | int transport_handle_cdb_direct( |
1205 | struct se_cmd *cmd) | 1173 | struct se_cmd *cmd) |
1206 | { | 1174 | { |
1207 | int ret; | 1175 | sense_reason_t ret; |
1208 | 1176 | ||
1209 | if (!cmd->se_lun) { | 1177 | if (!cmd->se_lun) { |
1210 | dump_stack(); | 1178 | dump_stack(); |
@@ -1234,13 +1202,41 @@ int transport_handle_cdb_direct( | |||
1234 | * and call transport_generic_request_failure() if necessary.. | 1202 | * and call transport_generic_request_failure() if necessary.. |
1235 | */ | 1203 | */ |
1236 | ret = transport_generic_new_cmd(cmd); | 1204 | ret = transport_generic_new_cmd(cmd); |
1237 | if (ret < 0) | 1205 | if (ret) |
1238 | transport_generic_request_failure(cmd); | 1206 | transport_generic_request_failure(cmd, ret); |
1239 | |||
1240 | return 0; | 1207 | return 0; |
1241 | } | 1208 | } |
1242 | EXPORT_SYMBOL(transport_handle_cdb_direct); | 1209 | EXPORT_SYMBOL(transport_handle_cdb_direct); |
1243 | 1210 | ||
1211 | static sense_reason_t | ||
1212 | transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *sgl, | ||
1213 | u32 sgl_count, struct scatterlist *sgl_bidi, u32 sgl_bidi_count) | ||
1214 | { | ||
1215 | if (!sgl || !sgl_count) | ||
1216 | return 0; | ||
1217 | |||
1218 | /* | ||
1219 | * Reject SCSI data overflow with map_mem_to_cmd() as incoming | ||
1220 | * scatterlists already have been set to follow what the fabric | ||
1221 | * passes for the original expected data transfer length. | ||
1222 | */ | ||
1223 | if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { | ||
1224 | pr_warn("Rejecting SCSI DATA overflow for fabric using" | ||
1225 | " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); | ||
1226 | return TCM_INVALID_CDB_FIELD; | ||
1227 | } | ||
1228 | |||
1229 | cmd->t_data_sg = sgl; | ||
1230 | cmd->t_data_nents = sgl_count; | ||
1231 | |||
1232 | if (sgl_bidi && sgl_bidi_count) { | ||
1233 | cmd->t_bidi_data_sg = sgl_bidi; | ||
1234 | cmd->t_bidi_data_nents = sgl_bidi_count; | ||
1235 | } | ||
1236 | cmd->se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC; | ||
1237 | return 0; | ||
1238 | } | ||
1239 | |||
1244 | /* | 1240 | /* |
1245 | * target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized | 1241 | * target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized |
1246 | * se_cmd + use pre-allocated SGL memory. | 1242 | * se_cmd + use pre-allocated SGL memory. |
@@ -1273,7 +1269,8 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess | |||
1273 | struct scatterlist *sgl_bidi, u32 sgl_bidi_count) | 1269 | struct scatterlist *sgl_bidi, u32 sgl_bidi_count) |
1274 | { | 1270 | { |
1275 | struct se_portal_group *se_tpg; | 1271 | struct se_portal_group *se_tpg; |
1276 | int rc; | 1272 | sense_reason_t rc; |
1273 | int ret; | ||
1277 | 1274 | ||
1278 | se_tpg = se_sess->se_tpg; | 1275 | se_tpg = se_sess->se_tpg; |
1279 | BUG_ON(!se_tpg); | 1276 | BUG_ON(!se_tpg); |
@@ -1294,9 +1291,9 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess | |||
1294 | * for fabrics using TARGET_SCF_ACK_KREF that expect a second | 1291 | * for fabrics using TARGET_SCF_ACK_KREF that expect a second |
1295 | * kref_put() to happen during fabric packet acknowledgement. | 1292 | * kref_put() to happen during fabric packet acknowledgement. |
1296 | */ | 1293 | */ |
1297 | rc = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF)); | 1294 | ret = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF)); |
1298 | if (rc) | 1295 | if (ret) |
1299 | return rc; | 1296 | return ret; |
1300 | /* | 1297 | /* |
1301 | * Signal bidirectional data payloads to target-core | 1298 | * Signal bidirectional data payloads to target-core |
1302 | */ | 1299 | */ |
@@ -1305,16 +1302,16 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess | |||
1305 | /* | 1302 | /* |
1306 | * Locate se_lun pointer and attach it to struct se_cmd | 1303 | * Locate se_lun pointer and attach it to struct se_cmd |
1307 | */ | 1304 | */ |
1308 | if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0) { | 1305 | rc = transport_lookup_cmd_lun(se_cmd, unpacked_lun); |
1309 | transport_send_check_condition_and_sense(se_cmd, | 1306 | if (rc) { |
1310 | se_cmd->scsi_sense_reason, 0); | 1307 | transport_send_check_condition_and_sense(se_cmd, rc, 0); |
1311 | target_put_sess_cmd(se_sess, se_cmd); | 1308 | target_put_sess_cmd(se_sess, se_cmd); |
1312 | return 0; | 1309 | return 0; |
1313 | } | 1310 | } |
1314 | 1311 | ||
1315 | rc = target_setup_cmd_from_cdb(se_cmd, cdb); | 1312 | rc = target_setup_cmd_from_cdb(se_cmd, cdb); |
1316 | if (rc != 0) { | 1313 | if (rc != 0) { |
1317 | transport_generic_request_failure(se_cmd); | 1314 | transport_generic_request_failure(se_cmd, rc); |
1318 | return 0; | 1315 | return 0; |
1319 | } | 1316 | } |
1320 | /* | 1317 | /* |
@@ -1349,7 +1346,7 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess | |||
1349 | rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count, | 1346 | rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count, |
1350 | sgl_bidi, sgl_bidi_count); | 1347 | sgl_bidi, sgl_bidi_count); |
1351 | if (rc != 0) { | 1348 | if (rc != 0) { |
1352 | transport_generic_request_failure(se_cmd); | 1349 | transport_generic_request_failure(se_cmd, rc); |
1353 | return 0; | 1350 | return 0; |
1354 | } | 1351 | } |
1355 | } | 1352 | } |
@@ -1495,16 +1492,17 @@ bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags) | |||
1495 | /* | 1492 | /* |
1496 | * Handle SAM-esque emulation for generic transport request failures. | 1493 | * Handle SAM-esque emulation for generic transport request failures. |
1497 | */ | 1494 | */ |
1498 | void transport_generic_request_failure(struct se_cmd *cmd) | 1495 | void transport_generic_request_failure(struct se_cmd *cmd, |
1496 | sense_reason_t sense_reason) | ||
1499 | { | 1497 | { |
1500 | int ret = 0; | 1498 | int ret = 0; |
1501 | 1499 | ||
1502 | pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" | 1500 | pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" |
1503 | " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), | 1501 | " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), |
1504 | cmd->t_task_cdb[0]); | 1502 | cmd->t_task_cdb[0]); |
1505 | pr_debug("-----[ i_state: %d t_state: %d scsi_sense_reason: %d\n", | 1503 | pr_debug("-----[ i_state: %d t_state: %d sense_reason: %d\n", |
1506 | cmd->se_tfo->get_cmd_state(cmd), | 1504 | cmd->se_tfo->get_cmd_state(cmd), |
1507 | cmd->t_state, cmd->scsi_sense_reason); | 1505 | cmd->t_state, sense_reason); |
1508 | pr_debug("-----[ CMD_T_ACTIVE: %d CMD_T_STOP: %d CMD_T_SENT: %d\n", | 1506 | pr_debug("-----[ CMD_T_ACTIVE: %d CMD_T_STOP: %d CMD_T_SENT: %d\n", |
1509 | (cmd->transport_state & CMD_T_ACTIVE) != 0, | 1507 | (cmd->transport_state & CMD_T_ACTIVE) != 0, |
1510 | (cmd->transport_state & CMD_T_STOP) != 0, | 1508 | (cmd->transport_state & CMD_T_STOP) != 0, |
@@ -1515,7 +1513,7 @@ void transport_generic_request_failure(struct se_cmd *cmd) | |||
1515 | */ | 1513 | */ |
1516 | transport_complete_task_attr(cmd); | 1514 | transport_complete_task_attr(cmd); |
1517 | 1515 | ||
1518 | switch (cmd->scsi_sense_reason) { | 1516 | switch (sense_reason) { |
1519 | case TCM_NON_EXISTENT_LUN: | 1517 | case TCM_NON_EXISTENT_LUN: |
1520 | case TCM_UNSUPPORTED_SCSI_OPCODE: | 1518 | case TCM_UNSUPPORTED_SCSI_OPCODE: |
1521 | case TCM_INVALID_CDB_FIELD: | 1519 | case TCM_INVALID_CDB_FIELD: |
@@ -1528,6 +1526,9 @@ void transport_generic_request_failure(struct se_cmd *cmd) | |||
1528 | case TCM_CHECK_CONDITION_UNIT_ATTENTION: | 1526 | case TCM_CHECK_CONDITION_UNIT_ATTENTION: |
1529 | case TCM_CHECK_CONDITION_NOT_READY: | 1527 | case TCM_CHECK_CONDITION_NOT_READY: |
1530 | break; | 1528 | break; |
1529 | case TCM_OUT_OF_RESOURCES: | ||
1530 | sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1531 | break; | ||
1531 | case TCM_RESERVATION_CONFLICT: | 1532 | case TCM_RESERVATION_CONFLICT: |
1532 | /* | 1533 | /* |
1533 | * No SENSE Data payload for this case, set SCSI Status | 1534 | * No SENSE Data payload for this case, set SCSI Status |
@@ -1555,13 +1556,12 @@ void transport_generic_request_failure(struct se_cmd *cmd) | |||
1555 | goto check_stop; | 1556 | goto check_stop; |
1556 | default: | 1557 | default: |
1557 | pr_err("Unknown transport error for CDB 0x%02x: %d\n", | 1558 | pr_err("Unknown transport error for CDB 0x%02x: %d\n", |
1558 | cmd->t_task_cdb[0], cmd->scsi_sense_reason); | 1559 | cmd->t_task_cdb[0], sense_reason); |
1559 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 1560 | sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
1560 | break; | 1561 | break; |
1561 | } | 1562 | } |
1562 | 1563 | ||
1563 | ret = transport_send_check_condition_and_sense(cmd, | 1564 | ret = transport_send_check_condition_and_sense(cmd, sense_reason, 0); |
1564 | cmd->scsi_sense_reason, 0); | ||
1565 | if (ret == -EAGAIN || ret == -ENOMEM) | 1565 | if (ret == -EAGAIN || ret == -ENOMEM) |
1566 | goto queue_full; | 1566 | goto queue_full; |
1567 | 1567 | ||
@@ -1579,21 +1579,21 @@ EXPORT_SYMBOL(transport_generic_request_failure); | |||
1579 | 1579 | ||
1580 | static void __target_execute_cmd(struct se_cmd *cmd) | 1580 | static void __target_execute_cmd(struct se_cmd *cmd) |
1581 | { | 1581 | { |
1582 | int error = 0; | 1582 | sense_reason_t ret; |
1583 | 1583 | ||
1584 | spin_lock_irq(&cmd->t_state_lock); | 1584 | spin_lock_irq(&cmd->t_state_lock); |
1585 | cmd->transport_state |= (CMD_T_BUSY|CMD_T_SENT); | 1585 | cmd->transport_state |= (CMD_T_BUSY|CMD_T_SENT); |
1586 | spin_unlock_irq(&cmd->t_state_lock); | 1586 | spin_unlock_irq(&cmd->t_state_lock); |
1587 | 1587 | ||
1588 | if (cmd->execute_cmd) | 1588 | if (cmd->execute_cmd) { |
1589 | error = cmd->execute_cmd(cmd); | 1589 | ret = cmd->execute_cmd(cmd); |
1590 | 1590 | if (ret) { | |
1591 | if (error) { | 1591 | spin_lock_irq(&cmd->t_state_lock); |
1592 | spin_lock_irq(&cmd->t_state_lock); | 1592 | cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT); |
1593 | cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT); | 1593 | spin_unlock_irq(&cmd->t_state_lock); |
1594 | spin_unlock_irq(&cmd->t_state_lock); | ||
1595 | 1594 | ||
1596 | transport_generic_request_failure(cmd); | 1595 | transport_generic_request_failure(cmd, ret); |
1596 | } | ||
1597 | } | 1597 | } |
1598 | } | 1598 | } |
1599 | 1599 | ||
@@ -1987,53 +1987,6 @@ out_busy: | |||
1987 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 1987 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
1988 | } | 1988 | } |
1989 | 1989 | ||
1990 | /* | ||
1991 | * transport_generic_map_mem_to_cmd - Use fabric-alloced pages instead of | ||
1992 | * allocating in the core. | ||
1993 | * @cmd: Associated se_cmd descriptor | ||
1994 | * @mem: SGL style memory for TCM WRITE / READ | ||
1995 | * @sg_mem_num: Number of SGL elements | ||
1996 | * @mem_bidi_in: SGL style memory for TCM BIDI READ | ||
1997 | * @sg_mem_bidi_num: Number of BIDI READ SGL elements | ||
1998 | * | ||
1999 | * Return: nonzero return cmd was rejected for -ENOMEM or inproper usage | ||
2000 | * of parameters. | ||
2001 | */ | ||
2002 | int transport_generic_map_mem_to_cmd( | ||
2003 | struct se_cmd *cmd, | ||
2004 | struct scatterlist *sgl, | ||
2005 | u32 sgl_count, | ||
2006 | struct scatterlist *sgl_bidi, | ||
2007 | u32 sgl_bidi_count) | ||
2008 | { | ||
2009 | if (!sgl || !sgl_count) | ||
2010 | return 0; | ||
2011 | |||
2012 | /* | ||
2013 | * Reject SCSI data overflow with map_mem_to_cmd() as incoming | ||
2014 | * scatterlists already have been set to follow what the fabric | ||
2015 | * passes for the original expected data transfer length. | ||
2016 | */ | ||
2017 | if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { | ||
2018 | pr_warn("Rejecting SCSI DATA overflow for fabric using" | ||
2019 | " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); | ||
2020 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
2021 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
2022 | return -EINVAL; | ||
2023 | } | ||
2024 | |||
2025 | cmd->t_data_sg = sgl; | ||
2026 | cmd->t_data_nents = sgl_count; | ||
2027 | |||
2028 | if (sgl_bidi && sgl_bidi_count) { | ||
2029 | cmd->t_bidi_data_sg = sgl_bidi; | ||
2030 | cmd->t_bidi_data_nents = sgl_bidi_count; | ||
2031 | } | ||
2032 | cmd->se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC; | ||
2033 | return 0; | ||
2034 | } | ||
2035 | EXPORT_SYMBOL(transport_generic_map_mem_to_cmd); | ||
2036 | |||
2037 | void *transport_kmap_data_sg(struct se_cmd *cmd) | 1990 | void *transport_kmap_data_sg(struct se_cmd *cmd) |
2038 | { | 1991 | { |
2039 | struct scatterlist *sg = cmd->t_data_sg; | 1992 | struct scatterlist *sg = cmd->t_data_sg; |
@@ -2054,10 +2007,8 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2054 | 2007 | ||
2055 | /* >1 page. use vmap */ | 2008 | /* >1 page. use vmap */ |
2056 | pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); | 2009 | pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); |
2057 | if (!pages) { | 2010 | if (!pages) |
2058 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2059 | return NULL; | 2011 | return NULL; |
2060 | } | ||
2061 | 2012 | ||
2062 | /* convert sg[] to pages[] */ | 2013 | /* convert sg[] to pages[] */ |
2063 | for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { | 2014 | for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { |
@@ -2066,10 +2017,8 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2066 | 2017 | ||
2067 | cmd->t_data_vmap = vmap(pages, cmd->t_data_nents, VM_MAP, PAGE_KERNEL); | 2018 | cmd->t_data_vmap = vmap(pages, cmd->t_data_nents, VM_MAP, PAGE_KERNEL); |
2068 | kfree(pages); | 2019 | kfree(pages); |
2069 | if (!cmd->t_data_vmap) { | 2020 | if (!cmd->t_data_vmap) |
2070 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2071 | return NULL; | 2021 | return NULL; |
2072 | } | ||
2073 | 2022 | ||
2074 | return cmd->t_data_vmap + cmd->t_data_sg[0].offset; | 2023 | return cmd->t_data_vmap + cmd->t_data_sg[0].offset; |
2075 | } | 2024 | } |
@@ -2135,7 +2084,8 @@ out: | |||
2135 | * might not have the payload yet, so notify the fabric via a call to | 2084 | * might not have the payload yet, so notify the fabric via a call to |
2136 | * ->write_pending instead. Otherwise place it on the execution queue. | 2085 | * ->write_pending instead. Otherwise place it on the execution queue. |
2137 | */ | 2086 | */ |
2138 | int transport_generic_new_cmd(struct se_cmd *cmd) | 2087 | sense_reason_t |
2088 | transport_generic_new_cmd(struct se_cmd *cmd) | ||
2139 | { | 2089 | { |
2140 | int ret = 0; | 2090 | int ret = 0; |
2141 | 2091 | ||
@@ -2148,7 +2098,7 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
2148 | cmd->data_length) { | 2098 | cmd->data_length) { |
2149 | ret = transport_generic_get_mem(cmd); | 2099 | ret = transport_generic_get_mem(cmd); |
2150 | if (ret < 0) | 2100 | if (ret < 0) |
2151 | goto out_fail; | 2101 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2152 | } | 2102 | } |
2153 | 2103 | ||
2154 | atomic_inc(&cmd->t_fe_count); | 2104 | atomic_inc(&cmd->t_fe_count); |
@@ -2174,14 +2124,11 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
2174 | if (ret == -EAGAIN || ret == -ENOMEM) | 2124 | if (ret == -EAGAIN || ret == -ENOMEM) |
2175 | goto queue_full; | 2125 | goto queue_full; |
2176 | 2126 | ||
2177 | if (ret < 0) | 2127 | /* fabric drivers should only return -EAGAIN or -ENOMEM as error */ |
2178 | return ret; | 2128 | WARN_ON(ret); |
2179 | return 1; | 2129 | |
2130 | return 0; | ||
2180 | 2131 | ||
2181 | out_fail: | ||
2182 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
2183 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2184 | return -EINVAL; | ||
2185 | queue_full: | 2132 | queue_full: |
2186 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); | 2133 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); |
2187 | cmd->t_state = TRANSPORT_COMPLETE_QF_WP; | 2134 | cmd->t_state = TRANSPORT_COMPLETE_QF_WP; |
@@ -2625,10 +2572,9 @@ static int transport_get_sense_codes( | |||
2625 | return 0; | 2572 | return 0; |
2626 | } | 2573 | } |
2627 | 2574 | ||
2628 | int transport_send_check_condition_and_sense( | 2575 | int |
2629 | struct se_cmd *cmd, | 2576 | transport_send_check_condition_and_sense(struct se_cmd *cmd, |
2630 | u8 reason, | 2577 | sense_reason_t reason, int from_transport) |
2631 | int from_transport) | ||
2632 | { | 2578 | { |
2633 | unsigned char *buffer = cmd->sense_buffer; | 2579 | unsigned char *buffer = cmd->sense_buffer; |
2634 | unsigned long flags; | 2580 | unsigned long flags; |
diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c index 59c95ee14749..60c8f41b9f1c 100644 --- a/drivers/target/target_core_ua.c +++ b/drivers/target/target_core_ua.c | |||
@@ -38,9 +38,8 @@ | |||
38 | #include "target_core_pr.h" | 38 | #include "target_core_pr.h" |
39 | #include "target_core_ua.h" | 39 | #include "target_core_ua.h" |
40 | 40 | ||
41 | int core_scsi3_ua_check( | 41 | sense_reason_t |
42 | struct se_cmd *cmd, | 42 | target_scsi3_ua_check(struct se_cmd *cmd) |
43 | unsigned char *cdb) | ||
44 | { | 43 | { |
45 | struct se_dev_entry *deve; | 44 | struct se_dev_entry *deve; |
46 | struct se_session *sess = cmd->se_sess; | 45 | struct se_session *sess = cmd->se_sess; |
@@ -71,16 +70,14 @@ int core_scsi3_ua_check( | |||
71 | * was received, then the device server shall process the command | 70 | * was received, then the device server shall process the command |
72 | * and either: | 71 | * and either: |
73 | */ | 72 | */ |
74 | switch (cdb[0]) { | 73 | switch (cmd->t_task_cdb[0]) { |
75 | case INQUIRY: | 74 | case INQUIRY: |
76 | case REPORT_LUNS: | 75 | case REPORT_LUNS: |
77 | case REQUEST_SENSE: | 76 | case REQUEST_SENSE: |
78 | return 0; | 77 | return 0; |
79 | default: | 78 | default: |
80 | return -EINVAL; | 79 | return TCM_CHECK_CONDITION_UNIT_ATTENTION; |
81 | } | 80 | } |
82 | |||
83 | return -EINVAL; | ||
84 | } | 81 | } |
85 | 82 | ||
86 | int core_scsi3_ua_allocate( | 83 | int core_scsi3_ua_allocate( |
diff --git a/drivers/target/target_core_ua.h b/drivers/target/target_core_ua.h index 6e6b03460a1a..0204952fe4d3 100644 --- a/drivers/target/target_core_ua.h +++ b/drivers/target/target_core_ua.h | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | extern struct kmem_cache *se_ua_cache; | 27 | extern struct kmem_cache *se_ua_cache; |
28 | 28 | ||
29 | extern int core_scsi3_ua_check(struct se_cmd *, unsigned char *); | 29 | extern sense_reason_t target_scsi3_ua_check(struct se_cmd *); |
30 | extern int core_scsi3_ua_allocate(struct se_node_acl *, u32, u8, u8); | 30 | extern int core_scsi3_ua_allocate(struct se_node_acl *, u32, u8, u8); |
31 | extern void core_scsi3_ua_release_all(struct se_dev_entry *); | 31 | extern void core_scsi3_ua_release_all(struct se_dev_entry *); |
32 | extern void core_scsi3_ua_for_check_condition(struct se_cmd *, u8 *, u8 *); | 32 | extern void core_scsi3_ua_for_check_condition(struct se_cmd *, u8 *, u8 *); |
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index aa31692064dd..6a69bf55aea9 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c | |||
@@ -541,10 +541,6 @@ static void tcm_vhost_submission_work(struct work_struct *work) | |||
541 | 541 | ||
542 | if (tv_cmd->tvc_sgl_count) { | 542 | if (tv_cmd->tvc_sgl_count) { |
543 | sg_ptr = tv_cmd->tvc_sgl; | 543 | sg_ptr = tv_cmd->tvc_sgl; |
544 | /* | ||
545 | * For BIDI commands, pass in the extra READ buffer | ||
546 | * to transport_generic_map_mem_to_cmd() below.. | ||
547 | */ | ||
548 | /* FIXME: Fix BIDI operation in tcm_vhost_submission_work() */ | 544 | /* FIXME: Fix BIDI operation in tcm_vhost_submission_work() */ |
549 | #if 0 | 545 | #if 0 |
550 | if (se_cmd->se_cmd_flags & SCF_BIDI) { | 546 | if (se_cmd->se_cmd_flags & SCF_BIDI) { |
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index e57f738f04f9..aa868090b9ab 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h | |||
@@ -31,17 +31,17 @@ struct se_subsystem_api { | |||
31 | struct scatterlist *, | 31 | struct scatterlist *, |
32 | unsigned char *); | 32 | unsigned char *); |
33 | 33 | ||
34 | int (*parse_cdb)(struct se_cmd *cmd); | 34 | sense_reason_t (*parse_cdb)(struct se_cmd *cmd); |
35 | u32 (*get_device_type)(struct se_device *); | 35 | u32 (*get_device_type)(struct se_device *); |
36 | sector_t (*get_blocks)(struct se_device *); | 36 | sector_t (*get_blocks)(struct se_device *); |
37 | unsigned char *(*get_sense_buffer)(struct se_cmd *); | 37 | unsigned char *(*get_sense_buffer)(struct se_cmd *); |
38 | }; | 38 | }; |
39 | 39 | ||
40 | struct sbc_ops { | 40 | struct sbc_ops { |
41 | int (*execute_rw)(struct se_cmd *cmd); | 41 | sense_reason_t (*execute_rw)(struct se_cmd *cmd); |
42 | int (*execute_sync_cache)(struct se_cmd *cmd); | 42 | sense_reason_t (*execute_sync_cache)(struct se_cmd *cmd); |
43 | int (*execute_write_same)(struct se_cmd *cmd); | 43 | sense_reason_t (*execute_write_same)(struct se_cmd *cmd); |
44 | int (*execute_unmap)(struct se_cmd *cmd); | 44 | sense_reason_t (*execute_unmap)(struct se_cmd *cmd); |
45 | }; | 45 | }; |
46 | 46 | ||
47 | int transport_subsystem_register(struct se_subsystem_api *); | 47 | int transport_subsystem_register(struct se_subsystem_api *); |
@@ -49,11 +49,11 @@ void transport_subsystem_release(struct se_subsystem_api *); | |||
49 | 49 | ||
50 | void target_complete_cmd(struct se_cmd *, u8); | 50 | void target_complete_cmd(struct se_cmd *, u8); |
51 | 51 | ||
52 | int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size); | 52 | sense_reason_t spc_parse_cdb(struct se_cmd *cmd, unsigned int *size); |
53 | int spc_emulate_report_luns(struct se_cmd *cmd); | 53 | sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd); |
54 | int spc_get_write_same_sectors(struct se_cmd *cmd); | 54 | int spc_get_write_same_sectors(struct se_cmd *cmd); |
55 | 55 | ||
56 | int sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops); | 56 | sense_reason_t sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops); |
57 | u32 sbc_get_device_rev(struct se_device *dev); | 57 | u32 sbc_get_device_rev(struct se_device *dev); |
58 | u32 sbc_get_device_type(struct se_device *dev); | 58 | u32 sbc_get_device_type(struct se_device *dev); |
59 | 59 | ||
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 11b0a68dc765..5350f6e580f0 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -144,8 +144,6 @@ enum se_cmd_flags_table { | |||
144 | SCF_EMULATED_TASK_SENSE = 0x00000004, | 144 | SCF_EMULATED_TASK_SENSE = 0x00000004, |
145 | SCF_SCSI_DATA_CDB = 0x00000008, | 145 | SCF_SCSI_DATA_CDB = 0x00000008, |
146 | SCF_SCSI_TMR_CDB = 0x00000010, | 146 | SCF_SCSI_TMR_CDB = 0x00000010, |
147 | SCF_SCSI_CDB_EXCEPTION = 0x00000020, | ||
148 | SCF_SCSI_RESERVATION_CONFLICT = 0x00000040, | ||
149 | SCF_FUA = 0x00000080, | 147 | SCF_FUA = 0x00000080, |
150 | SCF_SE_LUN_CMD = 0x00000100, | 148 | SCF_SE_LUN_CMD = 0x00000100, |
151 | SCF_BIDI = 0x00000400, | 149 | SCF_BIDI = 0x00000400, |
@@ -167,27 +165,32 @@ enum transport_lunflags_table { | |||
167 | }; | 165 | }; |
168 | 166 | ||
169 | /* | 167 | /* |
170 | * Used by transport_send_check_condition_and_sense() and se_cmd->scsi_sense_reason | 168 | * Used by transport_send_check_condition_and_sense() |
171 | * to signal which ASC/ASCQ sense payload should be built. | 169 | * to signal which ASC/ASCQ sense payload should be built. |
172 | */ | 170 | */ |
171 | typedef unsigned __bitwise__ sense_reason_t; | ||
172 | |||
173 | enum tcm_sense_reason_table { | 173 | enum tcm_sense_reason_table { |
174 | TCM_NON_EXISTENT_LUN = 0x01, | 174 | #define R(x) (__force sense_reason_t )(x) |
175 | TCM_UNSUPPORTED_SCSI_OPCODE = 0x02, | 175 | TCM_NON_EXISTENT_LUN = R(0x01), |
176 | TCM_INCORRECT_AMOUNT_OF_DATA = 0x03, | 176 | TCM_UNSUPPORTED_SCSI_OPCODE = R(0x02), |
177 | TCM_UNEXPECTED_UNSOLICITED_DATA = 0x04, | 177 | TCM_INCORRECT_AMOUNT_OF_DATA = R(0x03), |
178 | TCM_SERVICE_CRC_ERROR = 0x05, | 178 | TCM_UNEXPECTED_UNSOLICITED_DATA = R(0x04), |
179 | TCM_SNACK_REJECTED = 0x06, | 179 | TCM_SERVICE_CRC_ERROR = R(0x05), |
180 | TCM_SECTOR_COUNT_TOO_MANY = 0x07, | 180 | TCM_SNACK_REJECTED = R(0x06), |
181 | TCM_INVALID_CDB_FIELD = 0x08, | 181 | TCM_SECTOR_COUNT_TOO_MANY = R(0x07), |
182 | TCM_INVALID_PARAMETER_LIST = 0x09, | 182 | TCM_INVALID_CDB_FIELD = R(0x08), |
183 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE = 0x0a, | 183 | TCM_INVALID_PARAMETER_LIST = R(0x09), |
184 | TCM_UNKNOWN_MODE_PAGE = 0x0b, | 184 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE = R(0x0a), |
185 | TCM_WRITE_PROTECTED = 0x0c, | 185 | TCM_UNKNOWN_MODE_PAGE = R(0x0b), |
186 | TCM_CHECK_CONDITION_ABORT_CMD = 0x0d, | 186 | TCM_WRITE_PROTECTED = R(0x0c), |
187 | TCM_CHECK_CONDITION_UNIT_ATTENTION = 0x0e, | 187 | TCM_CHECK_CONDITION_ABORT_CMD = R(0x0d), |
188 | TCM_CHECK_CONDITION_NOT_READY = 0x0f, | 188 | TCM_CHECK_CONDITION_UNIT_ATTENTION = R(0x0e), |
189 | TCM_RESERVATION_CONFLICT = 0x10, | 189 | TCM_CHECK_CONDITION_NOT_READY = R(0x0f), |
190 | TCM_ADDRESS_OUT_OF_RANGE = 0x11, | 190 | TCM_RESERVATION_CONFLICT = R(0x10), |
191 | TCM_ADDRESS_OUT_OF_RANGE = R(0x11), | ||
192 | TCM_OUT_OF_RESOURCES = R(0x12), | ||
193 | #undef R | ||
191 | }; | 194 | }; |
192 | 195 | ||
193 | enum target_sc_flags_table { | 196 | enum target_sc_flags_table { |
@@ -407,7 +410,6 @@ struct se_cmd { | |||
407 | u8 scsi_status; | 410 | u8 scsi_status; |
408 | u8 scsi_asc; | 411 | u8 scsi_asc; |
409 | u8 scsi_ascq; | 412 | u8 scsi_ascq; |
410 | u8 scsi_sense_reason; | ||
411 | u16 scsi_sense_length; | 413 | u16 scsi_sense_length; |
412 | /* Delay for ALUA Active/NonOptimized state access in milliseconds */ | 414 | /* Delay for ALUA Active/NonOptimized state access in milliseconds */ |
413 | int alua_nonop_delay; | 415 | int alua_nonop_delay; |
@@ -445,7 +447,7 @@ struct se_cmd { | |||
445 | struct completion cmd_wait_comp; | 447 | struct completion cmd_wait_comp; |
446 | struct kref cmd_kref; | 448 | struct kref cmd_kref; |
447 | struct target_core_fabric_ops *se_tfo; | 449 | struct target_core_fabric_ops *se_tfo; |
448 | int (*execute_cmd)(struct se_cmd *); | 450 | sense_reason_t (*execute_cmd)(struct se_cmd *); |
449 | void (*transport_complete_callback)(struct se_cmd *); | 451 | void (*transport_complete_callback)(struct se_cmd *); |
450 | 452 | ||
451 | unsigned char *t_task_cdb; | 453 | unsigned char *t_task_cdb; |
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 81ddb4ae6c3f..9087b200e552 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h | |||
@@ -98,8 +98,8 @@ void transport_deregister_session(struct se_session *); | |||
98 | 98 | ||
99 | void transport_init_se_cmd(struct se_cmd *, struct target_core_fabric_ops *, | 99 | void transport_init_se_cmd(struct se_cmd *, struct target_core_fabric_ops *, |
100 | struct se_session *, u32, int, int, unsigned char *); | 100 | struct se_session *, u32, int, int, unsigned char *); |
101 | int transport_lookup_cmd_lun(struct se_cmd *, u32); | 101 | sense_reason_t transport_lookup_cmd_lun(struct se_cmd *, u32); |
102 | int target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *); | 102 | sense_reason_t target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *); |
103 | int target_submit_cmd_map_sgls(struct se_cmd *, struct se_session *, | 103 | int target_submit_cmd_map_sgls(struct se_cmd *, struct se_session *, |
104 | unsigned char *, unsigned char *, u32, u32, int, int, int, | 104 | unsigned char *, unsigned char *, u32, u32, int, int, int, |
105 | struct scatterlist *, u32, struct scatterlist *, u32); | 105 | struct scatterlist *, u32, struct scatterlist *, u32); |
@@ -110,9 +110,7 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, | |||
110 | void *fabric_tmr_ptr, unsigned char tm_type, | 110 | void *fabric_tmr_ptr, unsigned char tm_type, |
111 | gfp_t, unsigned int, int); | 111 | gfp_t, unsigned int, int); |
112 | int transport_handle_cdb_direct(struct se_cmd *); | 112 | int transport_handle_cdb_direct(struct se_cmd *); |
113 | int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, | 113 | sense_reason_t transport_generic_new_cmd(struct se_cmd *); |
114 | struct scatterlist *, u32, struct scatterlist *, u32); | ||
115 | int transport_generic_new_cmd(struct se_cmd *); | ||
116 | 114 | ||
117 | void target_execute_cmd(struct se_cmd *cmd); | 115 | void target_execute_cmd(struct se_cmd *cmd); |
118 | 116 | ||
@@ -120,7 +118,8 @@ void transport_generic_free_cmd(struct se_cmd *, int); | |||
120 | 118 | ||
121 | bool transport_wait_for_tasks(struct se_cmd *); | 119 | bool transport_wait_for_tasks(struct se_cmd *); |
122 | int transport_check_aborted_status(struct se_cmd *, int); | 120 | int transport_check_aborted_status(struct se_cmd *, int); |
123 | int transport_send_check_condition_and_sense(struct se_cmd *, u8, int); | 121 | int transport_send_check_condition_and_sense(struct se_cmd *, |
122 | sense_reason_t, int); | ||
124 | 123 | ||
125 | int target_put_sess_cmd(struct se_session *, struct se_cmd *); | 124 | int target_put_sess_cmd(struct se_session *, struct se_cmd *); |
126 | void target_sess_cmd_list_set_waiting(struct se_session *); | 125 | void target_sess_cmd_list_set_waiting(struct se_session *); |
@@ -131,7 +130,7 @@ int core_alua_check_nonop_delay(struct se_cmd *); | |||
131 | int core_tmr_alloc_req(struct se_cmd *, void *, u8, gfp_t); | 130 | int core_tmr_alloc_req(struct se_cmd *, void *, u8, gfp_t); |
132 | void core_tmr_release_req(struct se_tmr_req *); | 131 | void core_tmr_release_req(struct se_tmr_req *); |
133 | int transport_generic_handle_tmr(struct se_cmd *); | 132 | int transport_generic_handle_tmr(struct se_cmd *); |
134 | void transport_generic_request_failure(struct se_cmd *); | 133 | void transport_generic_request_failure(struct se_cmd *, sense_reason_t); |
135 | int transport_lookup_tmr_lun(struct se_cmd *, u32); | 134 | int transport_lookup_tmr_lun(struct se_cmd *, u32); |
136 | 135 | ||
137 | struct se_node_acl *core_tpg_check_initiator_node_acl(struct se_portal_group *, | 136 | struct se_node_acl *core_tpg_check_initiator_node_acl(struct se_portal_group *, |