Commit 03e98c9e authored by Nicholas Bellinger's avatar Nicholas Bellinger

target: Address legacy PYX_TRANSPORT_* return code breakage

This patch removes legacy usage of PYX_TRANSPORT_* return codes in a number
of locations and addresses cases where transport_generic_request_failure()
was returning the incorrect sense upon CHECK_CONDITION status after the
v3.1 converson to use errno return codes.

This includes the conversion of transport_generic_request_failure() to
process cmd->scsi_sense_reason and handle extra TCM_RESERVATION_CONFLICT
before calling transport_send_check_condition_and_sense() to queue up
response status.  It also drops PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES legacy
usgae, and returns TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE w/ a response
for these cases.

transport_generic_allocate_tasks(), transport_generic_new_cmd(), backend
SCF_SCSI_DATA_SG_IO_CDB ->do_task(), and emulated ->execute_task() have
all been updated to set se_cmd->scsi_sense_reason and return errno codes
universally upon failure.  This includes cmd->scsi_sense_reason assignment
in target_core_alua.c, target_core_pr.c and target_core_cdb.c emulation code.

Finally it updates fabric modules to remove the legacy usage, and for
TFO->new_cmd_map() callers forwards return values outside of fabric code.
iscsi-target has also been updated to remove a handful of special cases
related to the cleanup and signaling QUEUE_FULL handling w/ ft_write_pending()

(v2: Drop extra SCF_SCSI_CDB_EXCEPTION check during failure from
     transport_generic_new_cmd, and re-add missing task->task_error_status
     assignment in transport_complete_task)

Cc: Christoph Hellwig <hch@lst.de>
Cc: stable@kernel.org
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 5611cc45
...@@ -1017,11 +1017,6 @@ static int iscsit_handle_scsi_cmd( ...@@ -1017,11 +1017,6 @@ static int iscsit_handle_scsi_cmd(
" non-existent or non-exported iSCSI LUN:" " non-existent or non-exported iSCSI LUN:"
" 0x%016Lx\n", get_unaligned_le64(&hdr->lun)); " 0x%016Lx\n", get_unaligned_le64(&hdr->lun));
} }
if (ret == PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES)
return iscsit_add_reject_from_cmd(
ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1, 1, buf, cmd);
send_check_condition = 1; send_check_condition = 1;
goto attach_cmd; goto attach_cmd;
} }
...@@ -1123,7 +1118,7 @@ static int iscsit_handle_scsi_cmd( ...@@ -1123,7 +1118,7 @@ static int iscsit_handle_scsi_cmd(
* the backend memory allocation. * the backend memory allocation.
*/ */
ret = transport_generic_new_cmd(&cmd->se_cmd); ret = transport_generic_new_cmd(&cmd->se_cmd);
if ((ret < 0) || (cmd->se_cmd.se_cmd_flags & SCF_SE_CMD_FAILED)) { if (ret < 0) {
immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
dump_immediate_data = 1; dump_immediate_data = 1;
goto after_immediate_data; goto after_immediate_data;
...@@ -1341,7 +1336,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) ...@@ -1341,7 +1336,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
spin_lock_irqsave(&se_cmd->t_state_lock, flags); spin_lock_irqsave(&se_cmd->t_state_lock, flags);
if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) || if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) ||
(se_cmd->se_cmd_flags & SCF_SE_CMD_FAILED)) (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION))
dump_unsolicited_data = 1; dump_unsolicited_data = 1;
spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
......
...@@ -938,8 +938,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) ...@@ -938,8 +938,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
* handle the SCF_SCSI_RESERVATION_CONFLICT case here as well. * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well.
*/ */
if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) {
if (se_cmd->se_cmd_flags & if (se_cmd->scsi_sense_reason == TCM_RESERVATION_CONFLICT) {
SCF_SCSI_RESERVATION_CONFLICT) {
cmd->i_state = ISTATE_SEND_STATUS; cmd->i_state = ISTATE_SEND_STATUS;
spin_unlock_bh(&cmd->istate_lock); spin_unlock_bh(&cmd->istate_lock);
iscsit_add_cmd_to_response_queue(cmd, cmd->conn, iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
......
...@@ -148,22 +148,8 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd) ...@@ -148,22 +148,8 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
* Allocate the necessary tasks to complete the received CDB+data * Allocate the necessary tasks to complete the received CDB+data
*/ */
ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd); ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd);
if (ret == -ENOMEM) { if (ret != 0)
/* Out of Resources */ return ret;
return PYX_TRANSPORT_LU_COMM_FAILURE;
} else if (ret == -EINVAL) {
/*
* Handle case for SAM_STAT_RESERVATION_CONFLICT
*/
if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
return PYX_TRANSPORT_RESERVATION_CONFLICT;
/*
* Otherwise, return SAM_STAT_CHECK_CONDITION and return
* sense data.
*/
return PYX_TRANSPORT_USE_SENSE_REASON;
}
/* /*
* For BIDI commands, pass in the extra READ buffer * For BIDI commands, pass in the extra READ buffer
* to transport_generic_map_mem_to_cmd() below.. * to transport_generic_map_mem_to_cmd() below..
...@@ -194,12 +180,8 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd) ...@@ -194,12 +180,8 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
} }
/* Tell the core about our preallocated memory */ /* Tell the core about our preallocated memory */
ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), return transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
scsi_sg_count(sc), sgl_bidi, sgl_bidi_count); scsi_sg_count(sc), sgl_bidi, sgl_bidi_count);
if (ret < 0)
return PYX_TRANSPORT_LU_COMM_FAILURE;
return 0;
} }
/* /*
......
...@@ -191,9 +191,10 @@ int target_emulate_set_target_port_groups(struct se_task *task) ...@@ -191,9 +191,10 @@ int target_emulate_set_target_port_groups(struct se_task *task)
int alua_access_state, primary = 0, rc; int alua_access_state, primary = 0, rc;
u16 tg_pt_id, rtpi; u16 tg_pt_id, rtpi;
if (!l_port) if (!l_port) {
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
}
buf = transport_kmap_first_data_page(cmd); buf = transport_kmap_first_data_page(cmd);
/* /*
...@@ -203,7 +204,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) ...@@ -203,7 +204,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem;
if (!l_tg_pt_gp_mem) { if (!l_tg_pt_gp_mem) {
pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n");
rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
rc = -EINVAL;
goto out; goto out;
} }
spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
...@@ -211,7 +213,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) ...@@ -211,7 +213,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
if (!l_tg_pt_gp) { if (!l_tg_pt_gp) {
spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n");
rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
rc = -EINVAL;
goto out; goto out;
} }
rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA); rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA);
...@@ -220,7 +223,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) ...@@ -220,7 +223,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
if (!rc) { if (!rc) {
pr_debug("Unable to process SET_TARGET_PORT_GROUPS" pr_debug("Unable to process SET_TARGET_PORT_GROUPS"
" while TPGS_EXPLICT_ALUA is disabled\n"); " while TPGS_EXPLICT_ALUA is disabled\n");
rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
rc = -EINVAL;
goto out; goto out;
} }
...@@ -245,7 +249,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) ...@@ -245,7 +249,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
* REQUEST, and the additional sense code set to INVALID * REQUEST, and the additional sense code set to INVALID
* FIELD IN PARAMETER LIST. * FIELD IN PARAMETER LIST.
*/ */
rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
rc = -EINVAL;
goto out; goto out;
} }
rc = -1; rc = -1;
...@@ -298,7 +303,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) ...@@ -298,7 +303,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
* throw an exception with ASCQ: INVALID_PARAMETER_LIST * throw an exception with ASCQ: INVALID_PARAMETER_LIST
*/ */
if (rc != 0) { if (rc != 0) {
rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
rc = -EINVAL;
goto out; goto out;
} }
} else { } else {
...@@ -335,7 +341,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) ...@@ -335,7 +341,8 @@ int target_emulate_set_target_port_groups(struct se_task *task)
* INVALID_PARAMETER_LIST * INVALID_PARAMETER_LIST
*/ */
if (rc != 0) { if (rc != 0) {
rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
rc = -EINVAL;
goto out; goto out;
} }
} }
......
...@@ -703,6 +703,7 @@ int target_emulate_inquiry(struct se_task *task) ...@@ -703,6 +703,7 @@ int target_emulate_inquiry(struct se_task *task)
if (cmd->data_length < 4) { if (cmd->data_length < 4) {
pr_err("SCSI Inquiry payload length: %u" pr_err("SCSI Inquiry payload length: %u"
" too small for EVPD=1\n", cmd->data_length); " too small for EVPD=1\n", cmd->data_length);
cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL; return -EINVAL;
} }
...@@ -719,6 +720,7 @@ int target_emulate_inquiry(struct se_task *task) ...@@ -719,6 +720,7 @@ int target_emulate_inquiry(struct se_task *task)
} }
pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]);
cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
ret = -EINVAL; ret = -EINVAL;
out_unmap: out_unmap:
...@@ -969,7 +971,8 @@ int target_emulate_modesense(struct se_task *task) ...@@ -969,7 +971,8 @@ int target_emulate_modesense(struct se_task *task)
default: default:
pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n",
cdb[2] & 0x3f, cdb[3]); cdb[2] & 0x3f, cdb[3]);
return PYX_TRANSPORT_UNKNOWN_MODE_PAGE; cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE;
return -EINVAL;
} }
offset += length; offset += length;
...@@ -1027,7 +1030,8 @@ int target_emulate_request_sense(struct se_task *task) ...@@ -1027,7 +1030,8 @@ int target_emulate_request_sense(struct se_task *task)
if (cdb[1] & 0x01) { if (cdb[1] & 0x01) {
pr_err("REQUEST_SENSE description emulation not" pr_err("REQUEST_SENSE description emulation not"
" supported\n"); " supported\n");
return PYX_TRANSPORT_INVALID_CDB_FIELD; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -ENOSYS;
} }
buf = transport_kmap_first_data_page(cmd); buf = transport_kmap_first_data_page(cmd);
...@@ -1100,7 +1104,8 @@ int target_emulate_unmap(struct se_task *task) ...@@ -1100,7 +1104,8 @@ int target_emulate_unmap(struct se_task *task)
if (!dev->transport->do_discard) { if (!dev->transport->do_discard) {
pr_err("UNMAP emulation not supported for: %s\n", pr_err("UNMAP emulation not supported for: %s\n",
dev->transport->name); dev->transport->name);
return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
return -ENOSYS;
} }
/* First UNMAP block descriptor starts at 8 byte offset */ /* First UNMAP block descriptor starts at 8 byte offset */
...@@ -1157,7 +1162,8 @@ int target_emulate_write_same(struct se_task *task) ...@@ -1157,7 +1162,8 @@ int target_emulate_write_same(struct se_task *task)
if (!dev->transport->do_discard) { if (!dev->transport->do_discard) {
pr_err("WRITE_SAME emulation not supported" pr_err("WRITE_SAME emulation not supported"
" for: %s\n", dev->transport->name); " for: %s\n", dev->transport->name);
return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
return -ENOSYS;
} }
if (cmd->t_task_cdb[0] == WRITE_SAME) if (cmd->t_task_cdb[0] == WRITE_SAME)
...@@ -1193,11 +1199,13 @@ int target_emulate_write_same(struct se_task *task) ...@@ -1193,11 +1199,13 @@ int target_emulate_write_same(struct se_task *task)
int target_emulate_synchronize_cache(struct se_task *task) int target_emulate_synchronize_cache(struct se_task *task)
{ {
struct se_device *dev = task->task_se_cmd->se_dev; struct se_device *dev = task->task_se_cmd->se_dev;
struct se_cmd *cmd = task->task_se_cmd;
if (!dev->transport->do_sync_cache) { if (!dev->transport->do_sync_cache) {
pr_err("SYNCHRONIZE_CACHE emulation not supported" pr_err("SYNCHRONIZE_CACHE emulation not supported"
" for: %s\n", dev->transport->name); " for: %s\n", dev->transport->name);
return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
return -ENOSYS;
} }
dev->transport->do_sync_cache(task); dev->transport->do_sync_cache(task);
......
...@@ -708,7 +708,7 @@ int target_report_luns(struct se_task *se_task) ...@@ -708,7 +708,7 @@ int target_report_luns(struct se_task *se_task)
se_task->task_scsi_status = GOOD; se_task->task_scsi_status = GOOD;
transport_complete_task(se_task, 1); transport_complete_task(se_task, 1);
return PYX_TRANSPORT_SENT_TO_TRANSPORT; return 0;
} }
/* se_release_device_for_hba(): /* se_release_device_for_hba():
......
...@@ -449,13 +449,15 @@ static int fd_do_task(struct se_task *task) ...@@ -449,13 +449,15 @@ static int fd_do_task(struct se_task *task)
} }
if (ret < 0) if (ret < 0) {
cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return ret; return ret;
}
if (ret) { if (ret) {
task->task_scsi_status = GOOD; task->task_scsi_status = GOOD;
transport_complete_task(task, 1); transport_complete_task(task, 1);
} }
return PYX_TRANSPORT_SENT_TO_TRANSPORT; return 0;
} }
/* fd_free_task(): (Part of se_subsystem_api_t template) /* fd_free_task(): (Part of se_subsystem_api_t template)
......
...@@ -554,12 +554,15 @@ static int iblock_do_task(struct se_task *task) ...@@ -554,12 +554,15 @@ static int iblock_do_task(struct se_task *task)
else { else {
pr_err("Unsupported SCSI -> BLOCK LBA conversion:" pr_err("Unsupported SCSI -> BLOCK LBA conversion:"
" %u\n", dev->se_sub_dev->se_dev_attrib.block_size); " %u\n", dev->se_sub_dev->se_dev_attrib.block_size);
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -ENOSYS;
} }
bio = iblock_get_bio(task, block_lba, sg_num); bio = iblock_get_bio(task, block_lba, sg_num);
if (!bio) if (!bio) {
return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -ENOMEM;
}
bio_list_init(&list); bio_list_init(&list);
bio_list_add(&list, bio); bio_list_add(&list, bio);
...@@ -588,12 +591,13 @@ static int iblock_do_task(struct se_task *task) ...@@ -588,12 +591,13 @@ static int iblock_do_task(struct se_task *task)
submit_bio(rw, bio); submit_bio(rw, bio);
blk_finish_plug(&plug); blk_finish_plug(&plug);
return PYX_TRANSPORT_SENT_TO_TRANSPORT; return 0;
fail: fail:
while ((bio = bio_list_pop(&list))) while ((bio = bio_list_pop(&list)))
bio_put(bio); bio_put(bio);
return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -ENOMEM;
} }
static u32 iblock_get_device_rev(struct se_device *dev) static u32 iblock_get_device_rev(struct se_device *dev)
......
...@@ -191,7 +191,7 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) ...@@ -191,7 +191,7 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
pr_err("Received legacy SPC-2 RESERVE/RELEASE" pr_err("Received legacy SPC-2 RESERVE/RELEASE"
" while active SPC-3 registrations exist," " while active SPC-3 registrations exist,"
" returning RESERVATION_CONFLICT\n"); " returning RESERVATION_CONFLICT\n");
*ret = PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return true; return true;
} }
...@@ -252,7 +252,8 @@ int target_scsi2_reservation_reserve(struct se_task *task) ...@@ -252,7 +252,8 @@ int target_scsi2_reservation_reserve(struct se_task *task)
(cmd->t_task_cdb[1] & 0x02)) { (cmd->t_task_cdb[1] & 0x02)) {
pr_err("LongIO and Obselete Bits set, returning" pr_err("LongIO and Obselete Bits set, returning"
" ILLEGAL_REQUEST\n"); " ILLEGAL_REQUEST\n");
ret = PYX_TRANSPORT_ILLEGAL_REQUEST; cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
ret = -EINVAL;
goto out; goto out;
} }
/* /*
...@@ -277,7 +278,8 @@ int target_scsi2_reservation_reserve(struct se_task *task) ...@@ -277,7 +278,8 @@ int target_scsi2_reservation_reserve(struct se_task *task)
" from %s \n", cmd->se_lun->unpacked_lun, " from %s \n", cmd->se_lun->unpacked_lun,
cmd->se_deve->mapped_lun, cmd->se_deve->mapped_lun,
sess->se_node_acl->initiatorname); sess->se_node_acl->initiatorname);
ret = PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
ret = -EINVAL;
goto out_unlock; goto out_unlock;
} }
...@@ -1510,7 +1512,8 @@ static int core_scsi3_decode_spec_i_port( ...@@ -1510,7 +1512,8 @@ static int core_scsi3_decode_spec_i_port(
tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL);
if (!tidh_new) { if (!tidh_new) {
pr_err("Unable to allocate tidh_new\n"); pr_err("Unable to allocate tidh_new\n");
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
} }
INIT_LIST_HEAD(&tidh_new->dest_list); INIT_LIST_HEAD(&tidh_new->dest_list);
tidh_new->dest_tpg = tpg; tidh_new->dest_tpg = tpg;
...@@ -1522,7 +1525,8 @@ static int core_scsi3_decode_spec_i_port( ...@@ -1522,7 +1525,8 @@ static int core_scsi3_decode_spec_i_port(
sa_res_key, all_tg_pt, aptpl); sa_res_key, all_tg_pt, aptpl);
if (!local_pr_reg) { if (!local_pr_reg) {
kfree(tidh_new); kfree(tidh_new);
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -ENOMEM;
} }
tidh_new->dest_pr_reg = local_pr_reg; tidh_new->dest_pr_reg = local_pr_reg;
/* /*
...@@ -1548,7 +1552,8 @@ static int core_scsi3_decode_spec_i_port( ...@@ -1548,7 +1552,8 @@ static int core_scsi3_decode_spec_i_port(
pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header" pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header"
" does not equal CDB data_length: %u\n", tpdl, " does not equal CDB data_length: %u\n", tpdl,
cmd->data_length); cmd->data_length);
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
/* /*
...@@ -1598,7 +1603,9 @@ static int core_scsi3_decode_spec_i_port( ...@@ -1598,7 +1603,9 @@ static int core_scsi3_decode_spec_i_port(
" for tmp_tpg\n"); " for tmp_tpg\n");
atomic_dec(&tmp_tpg->tpg_pr_ref_count); atomic_dec(&tmp_tpg->tpg_pr_ref_count);
smp_mb__after_atomic_dec(); smp_mb__after_atomic_dec();
ret = PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason =
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
ret = -EINVAL;
goto out; goto out;
} }
/* /*
...@@ -1628,7 +1635,9 @@ static int core_scsi3_decode_spec_i_port( ...@@ -1628,7 +1635,9 @@ static int core_scsi3_decode_spec_i_port(
atomic_dec(&dest_node_acl->acl_pr_ref_count); atomic_dec(&dest_node_acl->acl_pr_ref_count);
smp_mb__after_atomic_dec(); smp_mb__after_atomic_dec();
core_scsi3_tpg_undepend_item(tmp_tpg); core_scsi3_tpg_undepend_item(tmp_tpg);
ret = PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason =
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
ret = -EINVAL;
goto out; goto out;
} }
...@@ -1646,7 +1655,8 @@ static int core_scsi3_decode_spec_i_port( ...@@ -1646,7 +1655,8 @@ static int core_scsi3_decode_spec_i_port(
if (!dest_tpg) { if (!dest_tpg) {
pr_err("SPC-3 PR SPEC_I_PT: Unable to locate" pr_err("SPC-3 PR SPEC_I_PT: Unable to locate"
" dest_tpg\n"); " dest_tpg\n");
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
#if 0 #if 0
...@@ -1660,7 +1670,8 @@ static int core_scsi3_decode_spec_i_port( ...@@ -1660,7 +1670,8 @@ static int core_scsi3_decode_spec_i_port(
" %u for Transport ID: %s\n", tid_len, ptr); " %u for Transport ID: %s\n", tid_len, ptr);
core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_nodeacl_undepend_item(dest_node_acl);
core_scsi3_tpg_undepend_item(dest_tpg); core_scsi3_tpg_undepend_item(dest_tpg);
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
/* /*
...@@ -1678,7 +1689,8 @@ static int core_scsi3_decode_spec_i_port( ...@@ -1678,7 +1689,8 @@ static int core_scsi3_decode_spec_i_port(
core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_nodeacl_undepend_item(dest_node_acl);
core_scsi3_tpg_undepend_item(dest_tpg); core_scsi3_tpg_undepend_item(dest_tpg);
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
...@@ -1690,7 +1702,9 @@ static int core_scsi3_decode_spec_i_port( ...@@ -1690,7 +1702,9 @@ static int core_scsi3_decode_spec_i_port(
smp_mb__after_atomic_dec(); smp_mb__after_atomic_dec();
core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_nodeacl_undepend_item(dest_node_acl);
core_scsi3_tpg_undepend_item(dest_tpg); core_scsi3_tpg_undepend_item(dest_tpg);
ret = PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason =
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
ret = -EINVAL;
goto out; goto out;
} }
#if 0 #if 0
...@@ -1727,7 +1741,9 @@ static int core_scsi3_decode_spec_i_port( ...@@ -1727,7 +1741,9 @@ static int core_scsi3_decode_spec_i_port(
core_scsi3_lunacl_undepend_item(dest_se_deve); core_scsi3_lunacl_undepend_item(dest_se_deve);
core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_nodeacl_undepend_item(dest_node_acl);
core_scsi3_tpg_undepend_item(dest_tpg); core_scsi3_tpg_undepend_item(dest_tpg);
ret = PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason =
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
ret = -ENOMEM;
goto out; goto out;
} }
INIT_LIST_HEAD(&tidh_new->dest_list); INIT_LIST_HEAD(&tidh_new->dest_list);
...@@ -1759,7 +1775,8 @@ static int core_scsi3_decode_spec_i_port( ...@@ -1759,7 +1775,8 @@ static int core_scsi3_decode_spec_i_port(
core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_nodeacl_undepend_item(dest_node_acl);
core_scsi3_tpg_undepend_item(dest_tpg); core_scsi3_tpg_undepend_item(dest_tpg);
kfree(tidh_new); kfree(tidh_new);
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
tidh_new->dest_pr_reg = dest_pr_reg; tidh_new->dest_pr_reg = dest_pr_reg;
...@@ -2098,7 +2115,8 @@ static int core_scsi3_emulate_pro_register( ...@@ -2098,7 +2115,8 @@ static int core_scsi3_emulate_pro_register(
if (!se_sess || !se_lun) { if (!se_sess || !se_lun) {
pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
} }
se_tpg = se_sess->se_tpg; se_tpg = se_sess->se_tpg;
se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
...@@ -2117,13 +2135,14 @@ static int core_scsi3_emulate_pro_register( ...@@ -2117,13 +2135,14 @@ static int core_scsi3_emulate_pro_register(
if (res_key) { if (res_key) {
pr_warn("SPC-3 PR: Reservation Key non-zero" pr_warn("SPC-3 PR: Reservation Key non-zero"
" for SA REGISTER, returning CONFLICT\n"); " for SA REGISTER, returning CONFLICT\n");
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
/* /*
* Do nothing but return GOOD status. * Do nothing but return GOOD status.
*/ */
if (!sa_res_key) if (!sa_res_key)
return PYX_TRANSPORT_SENT_TO_TRANSPORT; return 0;
if (!spec_i_pt) { if (!spec_i_pt) {
/* /*
...@@ -2138,7 +2157,8 @@ static int core_scsi3_emulate_pro_register( ...@@ -2138,7 +2157,8 @@ static int core_scsi3_emulate_pro_register(
if (ret != 0) { if (ret != 0) {
pr_err("Unable to allocate" pr_err("Unable to allocate"
" struct t10_pr_registration\n"); " struct t10_pr_registration\n");
return PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
return -EINVAL;
} }
} else { } else {
/* /*
...@@ -2197,14 +2217,16 @@ static int core_scsi3_emulate_pro_register( ...@@ -2197,14 +2217,16 @@ static int core_scsi3_emulate_pro_register(
" 0x%016Lx\n", res_key, " 0x%016Lx\n", res_key,
pr_reg->pr_res_key); pr_reg->pr_res_key);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
} }
if (spec_i_pt) { if (spec_i_pt) {
pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT"
" set while sa_res_key=0\n"); " set while sa_res_key=0\n");
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
return -EINVAL;
} }
/* /*
* An existing ALL_TG_PT=1 registration being released * An existing ALL_TG_PT=1 registration being released
...@@ -2215,7 +2237,8 @@ static int core_scsi3_emulate_pro_register( ...@@ -2215,7 +2237,8 @@ static int core_scsi3_emulate_pro_register(
" registration exists, but ALL_TG_PT=1 bit not" " registration exists, but ALL_TG_PT=1 bit not"
" present in received PROUT\n"); " present in received PROUT\n");
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_INVALID_CDB_FIELD; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
} }
/* /*
* Allocate APTPL metadata buffer used for UNREGISTER ops * Allocate APTPL metadata buffer used for UNREGISTER ops
...@@ -2227,7 +2250,9 @@ static int core_scsi3_emulate_pro_register( ...@@ -2227,7 +2250,9 @@ static int core_scsi3_emulate_pro_register(
pr_err("Unable to allocate" pr_err("Unable to allocate"
" pr_aptpl_buf\n"); " pr_aptpl_buf\n");
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason =
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
} }
} }
/* /*
...@@ -2241,7 +2266,8 @@ static int core_scsi3_emulate_pro_register( ...@@ -2241,7 +2266,8 @@ static int core_scsi3_emulate_pro_register(
if (pr_holder < 0) { if (pr_holder < 0) {
kfree(pr_aptpl_buf); kfree(pr_aptpl_buf);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
spin_lock(&pr_tmpl->registration_lock); spin_lock(&pr_tmpl->registration_lock);
...@@ -2405,7 +2431,8 @@ static int core_scsi3_pro_reserve( ...@@ -2405,7 +2431,8 @@ static int core_scsi3_pro_reserve(
if (!se_sess || !se_lun) { if (!se_sess || !se_lun) {
pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
} }
se_tpg = se_sess->se_tpg; se_tpg = se_sess->se_tpg;
se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
...@@ -2417,7 +2444,8 @@ static int core_scsi3_pro_reserve( ...@@ -2417,7 +2444,8 @@ static int core_scsi3_pro_reserve(
if (!pr_reg) { if (!pr_reg) {
pr_err("SPC-3 PR: Unable to locate" pr_err("SPC-3 PR: Unable to locate"
" PR_REGISTERED *pr_reg for RESERVE\n"); " PR_REGISTERED *pr_reg for RESERVE\n");
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
} }
/* /*
* From spc4r17 Section 5.7.9: Reserving: * From spc4r17 Section 5.7.9: Reserving:
...@@ -2433,7 +2461,8 @@ static int core_scsi3_pro_reserve( ...@@ -2433,7 +2461,8 @@ static int core_scsi3_pro_reserve(
" does not match existing SA REGISTER res_key:" " does not match existing SA REGISTER res_key:"
" 0x%016Lx\n", res_key, pr_reg->pr_res_key); " 0x%016Lx\n", res_key, pr_reg->pr_res_key);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
/* /*
* From spc4r17 Section 5.7.9: Reserving: * From spc4r17 Section 5.7.9: Reserving:
...@@ -2448,7 +2477,8 @@ static int core_scsi3_pro_reserve( ...@@ -2448,7 +2477,8 @@ static int core_scsi3_pro_reserve(
if (scope != PR_SCOPE_LU_SCOPE) { if (scope != PR_SCOPE_LU_SCOPE) {
pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
return -EINVAL;
} }
/* /*
* See if we have an existing PR reservation holder pointer at * See if we have an existing PR reservation holder pointer at
...@@ -2480,7 +2510,8 @@ static int core_scsi3_pro_reserve( ...@@ -2480,7 +2510,8 @@ static int core_scsi3_pro_reserve(
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
/* /*
* From spc4r17 Section 5.7.9: Reserving: * From spc4r17 Section 5.7.9: Reserving:
...@@ -2503,7 +2534,8 @@ static int core_scsi3_pro_reserve( ...@@ -2503,7 +2534,8 @@ static int core_scsi3_pro_reserve(
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
/* /*
* From spc4r17 Section 5.7.9: Reserving: * From spc4r17 Section 5.7.9: Reserving:
...@@ -2517,7 +2549,7 @@ static int core_scsi3_pro_reserve( ...@@ -2517,7 +2549,7 @@ static int core_scsi3_pro_reserve(
*/ */
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_SENT_TO_TRANSPORT; return 0;
} }
/* /*
* Otherwise, our *pr_reg becomes the PR reservation holder for said * Otherwise, our *pr_reg becomes the PR reservation holder for said
...@@ -2574,7 +2606,8 @@ static int core_scsi3_emulate_pro_reserve( ...@@ -2574,7 +2606,8 @@ static int core_scsi3_emulate_pro_reserve(
default: default:
pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:" pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:"
" 0x%02x\n", type); " 0x%02x\n", type);
return PYX_TRANSPORT_INVALID_CDB_FIELD; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
} }
return ret; return ret;
...@@ -2630,7 +2663,8 @@ static int core_scsi3_emulate_pro_release( ...@@ -2630,7 +2663,8 @@ static int core_scsi3_emulate_pro_release(
if (!se_sess || !se_lun) { if (!se_sess || !se_lun) {
pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
} }
/* /*
* Locate the existing *pr_reg via struct se_node_acl pointers * Locate the existing *pr_reg via struct se_node_acl pointers
...@@ -2639,7 +2673,8 @@ static int core_scsi3_emulate_pro_release( ...@@ -2639,7 +2673,8 @@ static int core_scsi3_emulate_pro_release(
if (!pr_reg) { if (!pr_reg) {
pr_err("SPC-3 PR: Unable to locate" pr_err("SPC-3 PR: Unable to locate"
" PR_REGISTERED *pr_reg for RELEASE\n"); " PR_REGISTERED *pr_reg for RELEASE\n");
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
} }
/* /*
* From spc4r17 Section 5.7.11.2 Releasing: * From spc4r17 Section 5.7.11.2 Releasing:
...@@ -2661,7 +2696,7 @@ static int core_scsi3_emulate_pro_release( ...@@ -2661,7 +2696,7 @@ static int core_scsi3_emulate_pro_release(
*/ */
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_SENT_TO_TRANSPORT; return 0;
} }
if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
(pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG))
...@@ -2675,7 +2710,7 @@ static int core_scsi3_emulate_pro_release( ...@@ -2675,7 +2710,7 @@ static int core_scsi3_emulate_pro_release(
*/ */
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_SENT_TO_TRANSPORT; return 0;
} }
/* /*
* From spc4r17 Section 5.7.11.2 Releasing: * From spc4r17 Section 5.7.11.2 Releasing:
...@@ -2697,7 +2732,8 @@ static int core_scsi3_emulate_pro_release( ...@@ -2697,7 +2732,8 @@ static int core_scsi3_emulate_pro_release(
" 0x%016Lx\n", res_key, pr_reg->pr_res_key); " 0x%016Lx\n", res_key, pr_reg->pr_res_key);
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
/* /*
* From spc4r17 Section 5.7.11.2 Releasing and above: * From spc4r17 Section 5.7.11.2 Releasing and above:
...@@ -2719,7 +2755,8 @@ static int core_scsi3_emulate_pro_release( ...@@ -2719,7 +2755,8 @@ static int core_scsi3_emulate_pro_release(
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
/* /*
* In response to a persistent reservation release request from the * In response to a persistent reservation release request from the
...@@ -2802,7 +2839,8 @@ static int core_scsi3_emulate_pro_clear( ...@@ -2802,7 +2839,8 @@ static int core_scsi3_emulate_pro_clear(
if (!pr_reg_n) { if (!pr_reg_n) {
pr_err("SPC-3 PR: Unable to locate" pr_err("SPC-3 PR: Unable to locate"
" PR_REGISTERED *pr_reg for CLEAR\n"); " PR_REGISTERED *pr_reg for CLEAR\n");
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
} }
/* /*
* From spc4r17 section 5.7.11.6, Clearing: * From spc4r17 section 5.7.11.6, Clearing:
...@@ -2821,7 +2859,8 @@ static int core_scsi3_emulate_pro_clear( ...@@ -2821,7 +2859,8 @@ static int core_scsi3_emulate_pro_clear(
" existing SA REGISTER res_key:" " existing SA REGISTER res_key:"
" 0x%016Lx\n", res_key, pr_reg_n->pr_res_key); " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key);
core_scsi3_put_pr_reg(pr_reg_n); core_scsi3_put_pr_reg(pr_reg_n);
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
/* /*
* a) Release the persistent reservation, if any; * a) Release the persistent reservation, if any;
...@@ -2979,8 +3018,10 @@ static int core_scsi3_pro_preempt( ...@@ -2979,8 +3018,10 @@ static int core_scsi3_pro_preempt(
int all_reg = 0, calling_it_nexus = 0, released_regs = 0; int all_reg = 0, calling_it_nexus = 0, released_regs = 0;
int prh_type = 0, prh_scope = 0, ret; int prh_type = 0, prh_scope = 0, ret;
if (!se_sess) if (!se_sess) {
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
}
se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
...@@ -2989,16 +3030,19 @@ static int core_scsi3_pro_preempt( ...@@ -2989,16 +3030,19 @@ static int core_scsi3_pro_preempt(
pr_err("SPC-3 PR: Unable to locate" pr_err("SPC-3 PR: Unable to locate"
" PR_REGISTERED *pr_reg for PREEMPT%s\n", " PR_REGISTERED *pr_reg for PREEMPT%s\n",
(abort) ? "_AND_ABORT" : ""); (abort) ? "_AND_ABORT" : "");
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
if (pr_reg_n->pr_res_key != res_key) { if (pr_reg_n->pr_res_key != res_key) {
core_scsi3_put_pr_reg(pr_reg_n); core_scsi3_put_pr_reg(pr_reg_n);
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
if (scope != PR_SCOPE_LU_SCOPE) { if (scope != PR_SCOPE_LU_SCOPE) {
pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
core_scsi3_put_pr_reg(pr_reg_n); core_scsi3_put_pr_reg(pr_reg_n);
return PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
return -EINVAL;
} }
INIT_LIST_HEAD(&preempt_and_abort_list); INIT_LIST_HEAD(&preempt_and_abort_list);
...@@ -3012,7 +3056,8 @@ static int core_scsi3_pro_preempt( ...@@ -3012,7 +3056,8 @@ static int core_scsi3_pro_preempt(
if (!all_reg && !sa_res_key) { if (!all_reg && !sa_res_key) {
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
core_scsi3_put_pr_reg(pr_reg_n); core_scsi3_put_pr_reg(pr_reg_n);
return PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
return -EINVAL;
} }
/* /*
* From spc4r17, section 5.7.11.4.4 Removing Registrations: * From spc4r17, section 5.7.11.4.4 Removing Registrations:
...@@ -3106,7 +3151,8 @@ static int core_scsi3_pro_preempt( ...@@ -3106,7 +3151,8 @@ static int core_scsi3_pro_preempt(
if (!released_regs) { if (!released_regs) {
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
core_scsi3_put_pr_reg(pr_reg_n); core_scsi3_put_pr_reg(pr_reg_n);
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
/* /*
* For an existing all registrants type reservation * For an existing all registrants type reservation
...@@ -3297,7 +3343,8 @@ static int core_scsi3_emulate_pro_preempt( ...@@ -3297,7 +3343,8 @@ static int core_scsi3_emulate_pro_preempt(
default: default:
pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s"
" Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type);
return PYX_TRANSPORT_INVALID_CDB_FIELD; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
} }
return ret; return ret;
...@@ -3331,7 +3378,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3331,7 +3378,8 @@ static int core_scsi3_emulate_pro_register_and_move(
if (!se_sess || !se_lun) { if (!se_sess || !se_lun) {
pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
} }
memset(dest_iport, 0, 64); memset(dest_iport, 0, 64);
memset(i_buf, 0, PR_REG_ISID_ID_LEN); memset(i_buf, 0, PR_REG_ISID_ID_LEN);
...@@ -3349,7 +3397,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3349,7 +3397,8 @@ static int core_scsi3_emulate_pro_register_and_move(
if (!pr_reg) { if (!pr_reg) {
pr_err("SPC-3 PR: Unable to locate PR_REGISTERED" pr_err("SPC-3 PR: Unable to locate PR_REGISTERED"
" *pr_reg for REGISTER_AND_MOVE\n"); " *pr_reg for REGISTER_AND_MOVE\n");
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
} }
/* /*
* The provided reservation key much match the existing reservation key * The provided reservation key much match the existing reservation key
...@@ -3360,7 +3409,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3360,7 +3409,8 @@ static int core_scsi3_emulate_pro_register_and_move(
" res_key: 0x%016Lx does not match existing SA REGISTER" " res_key: 0x%016Lx does not match existing SA REGISTER"
" res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key); " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
/* /*
* The service active reservation key needs to be non zero * The service active reservation key needs to be non zero
...@@ -3369,7 +3419,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3369,7 +3419,8 @@ static int core_scsi3_emulate_pro_register_and_move(
pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero" pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero"
" sa_res_key\n"); " sa_res_key\n");
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
return -EINVAL;
} }
/* /*
...@@ -3392,7 +3443,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3392,7 +3443,8 @@ static int core_scsi3_emulate_pro_register_and_move(
" does not equal CDB data_length: %u\n", tid_len, " does not equal CDB data_length: %u\n", tid_len,
cmd->data_length); cmd->data_length);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
return -EINVAL;
} }
spin_lock(&dev->se_port_lock); spin_lock(&dev->se_port_lock);
...@@ -3417,7 +3469,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3417,7 +3469,8 @@ static int core_scsi3_emulate_pro_register_and_move(
atomic_dec(&dest_se_tpg->tpg_pr_ref_count); atomic_dec(&dest_se_tpg->tpg_pr_ref_count);
smp_mb__after_atomic_dec(); smp_mb__after_atomic_dec();
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
} }
spin_lock(&dev->se_port_lock); spin_lock(&dev->se_port_lock);
...@@ -3430,7 +3483,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3430,7 +3483,8 @@ static int core_scsi3_emulate_pro_register_and_move(
" fabric ops from Relative Target Port Identifier:" " fabric ops from Relative Target Port Identifier:"
" %hu\n", rtpi); " %hu\n", rtpi);
core_scsi3_put_pr_reg(pr_reg); core_scsi3_put_pr_reg(pr_reg);
return PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
return -EINVAL;
} }
buf = transport_kmap_first_data_page(cmd); buf = transport_kmap_first_data_page(cmd);
...@@ -3445,14 +3499,16 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3445,14 +3499,16 @@ static int core_scsi3_emulate_pro_register_and_move(
" from fabric: %s\n", proto_ident, " from fabric: %s\n", proto_ident,
dest_tf_ops->get_fabric_proto_ident(dest_se_tpg), dest_tf_ops->get_fabric_proto_ident(dest_se_tpg),
dest_tf_ops->get_fabric_name()); dest_tf_ops->get_fabric_name());
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) { if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) {
pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not" pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not"
" containg a valid tpg_parse_pr_out_transport_id" " containg a valid tpg_parse_pr_out_transport_id"
" function pointer\n"); " function pointer\n");
ret = PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
ret = -EINVAL;
goto out; goto out;
} }
initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg, initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg,
...@@ -3460,7 +3516,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3460,7 +3516,8 @@ static int core_scsi3_emulate_pro_register_and_move(
if (!initiator_str) { if (!initiator_str) {
pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
" initiator_str from Transport ID\n"); " initiator_str from Transport ID\n");
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
...@@ -3489,7 +3546,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3489,7 +3546,8 @@ static int core_scsi3_emulate_pro_register_and_move(
pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s" pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s"
" matches: %s on received I_T Nexus\n", initiator_str, " matches: %s on received I_T Nexus\n", initiator_str,
pr_reg_nacl->initiatorname); pr_reg_nacl->initiatorname);
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) { if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) {
...@@ -3497,7 +3555,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3497,7 +3555,8 @@ static int core_scsi3_emulate_pro_register_and_move(
" matches: %s %s on received I_T Nexus\n", " matches: %s %s on received I_T Nexus\n",
initiator_str, iport_ptr, pr_reg_nacl->initiatorname, initiator_str, iport_ptr, pr_reg_nacl->initiatorname,
pr_reg->pr_reg_isid); pr_reg->pr_reg_isid);
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
after_iport_check: after_iport_check:
...@@ -3517,7 +3576,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3517,7 +3576,8 @@ static int core_scsi3_emulate_pro_register_and_move(
pr_err("Unable to locate %s dest_node_acl for" pr_err("Unable to locate %s dest_node_acl for"
" TransportID%s\n", dest_tf_ops->get_fabric_name(), " TransportID%s\n", dest_tf_ops->get_fabric_name(),
initiator_str); initiator_str);
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
ret = core_scsi3_nodeacl_depend_item(dest_node_acl); ret = core_scsi3_nodeacl_depend_item(dest_node_acl);
...@@ -3527,7 +3587,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3527,7 +3587,8 @@ static int core_scsi3_emulate_pro_register_and_move(
atomic_dec(&dest_node_acl->acl_pr_ref_count); atomic_dec(&dest_node_acl->acl_pr_ref_count);
smp_mb__after_atomic_dec(); smp_mb__after_atomic_dec();
dest_node_acl = NULL; dest_node_acl = NULL;
ret = PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
#if 0 #if 0
...@@ -3543,7 +3604,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3543,7 +3604,8 @@ static int core_scsi3_emulate_pro_register_and_move(
if (!dest_se_deve) { if (!dest_se_deve) {
pr_err("Unable to locate %s dest_se_deve from RTPI:" pr_err("Unable to locate %s dest_se_deve from RTPI:"
" %hu\n", dest_tf_ops->get_fabric_name(), rtpi); " %hu\n", dest_tf_ops->get_fabric_name(), rtpi);
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
...@@ -3553,7 +3615,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3553,7 +3615,8 @@ static int core_scsi3_emulate_pro_register_and_move(
atomic_dec(&dest_se_deve->pr_ref_count); atomic_dec(&dest_se_deve->pr_ref_count);
smp_mb__after_atomic_dec(); smp_mb__after_atomic_dec();
dest_se_deve = NULL; dest_se_deve = NULL;
ret = PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
ret = -EINVAL;
goto out; goto out;
} }
#if 0 #if 0
...@@ -3572,7 +3635,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3572,7 +3635,8 @@ static int core_scsi3_emulate_pro_register_and_move(
pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation" pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation"
" currently held\n"); " currently held\n");
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
ret = PYX_TRANSPORT_INVALID_CDB_FIELD; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
ret = -EINVAL;
goto out; goto out;
} }
/* /*
...@@ -3585,7 +3649,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3585,7 +3649,8 @@ static int core_scsi3_emulate_pro_register_and_move(
pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T"
" Nexus is not reservation holder\n"); " Nexus is not reservation holder\n");
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
ret = PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
ret = -EINVAL;
goto out; goto out;
} }
/* /*
...@@ -3603,7 +3668,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3603,7 +3668,8 @@ static int core_scsi3_emulate_pro_register_and_move(
" reservation for type: %s\n", " reservation for type: %s\n",
core_scsi3_pr_dump_type(pr_res_holder->pr_res_type)); core_scsi3_pr_dump_type(pr_res_holder->pr_res_type));
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
ret = PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
ret = -EINVAL;
goto out; goto out;
} }
pr_res_nacl = pr_res_holder->pr_reg_nacl; pr_res_nacl = pr_res_holder->pr_reg_nacl;
...@@ -3640,7 +3706,8 @@ static int core_scsi3_emulate_pro_register_and_move( ...@@ -3640,7 +3706,8 @@ static int core_scsi3_emulate_pro_register_and_move(
sa_res_key, 0, aptpl, 2, 1); sa_res_key, 0, aptpl, 2, 1);
if (ret != 0) { if (ret != 0) {
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
...@@ -3771,7 +3838,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) ...@@ -3771,7 +3838,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task)
pr_err("Received PERSISTENT_RESERVE CDB while legacy" pr_err("Received PERSISTENT_RESERVE CDB while legacy"
" SPC-2 reservation is held, returning" " SPC-2 reservation is held, returning"
" RESERVATION_CONFLICT\n"); " RESERVATION_CONFLICT\n");
ret = PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
ret = EINVAL;
goto out; goto out;
} }
...@@ -3779,13 +3847,16 @@ int target_scsi3_emulate_pr_out(struct se_task *task) ...@@ -3779,13 +3847,16 @@ int target_scsi3_emulate_pr_out(struct se_task *task)
* FIXME: A NULL struct se_session pointer means an this is not coming from * FIXME: A NULL struct se_session pointer means an this is not coming from
* a $FABRIC_MOD's nexus, but from internal passthrough ops. * a $FABRIC_MOD's nexus, but from internal passthrough ops.
*/ */
if (!cmd->se_sess) if (!cmd->se_sess) {
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -EINVAL;
}
if (cmd->data_length < 24) { if (cmd->data_length < 24) {
pr_warn("SPC-PR: Received PR OUT parameter list" pr_warn("SPC-PR: Received PR OUT parameter list"
" length too small: %u\n", cmd->data_length); " length too small: %u\n", cmd->data_length);
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
/* /*
...@@ -3820,7 +3891,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) ...@@ -3820,7 +3891,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task)
* SPEC_I_PT=1 is only valid for Service action: REGISTER * SPEC_I_PT=1 is only valid for Service action: REGISTER
*/ */
if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) { if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) {
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
...@@ -3837,7 +3909,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) ...@@ -3837,7 +3909,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task)
(cmd->data_length != 24)) { (cmd->data_length != 24)) {
pr_warn("SPC-PR: Received PR OUT illegal parameter" pr_warn("SPC-PR: Received PR OUT illegal parameter"
" list length: %u\n", cmd->data_length); " list length: %u\n", cmd->data_length);
ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
ret = -EINVAL;
goto out; goto out;
} }
/* /*
...@@ -3878,7 +3951,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) ...@@ -3878,7 +3951,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task)
default: default:
pr_err("Unknown PERSISTENT_RESERVE_OUT service" pr_err("Unknown PERSISTENT_RESERVE_OUT service"
" action: 0x%02x\n", cdb[1] & 0x1f); " action: 0x%02x\n", cdb[1] & 0x1f);
ret = PYX_TRANSPORT_INVALID_CDB_FIELD; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
ret = -EINVAL;
break; break;
} }
...@@ -3906,7 +3980,8 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd) ...@@ -3906,7 +3980,8 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
if (cmd->data_length < 8) { if (cmd->data_length < 8) {
pr_err("PRIN SA READ_KEYS SCSI Data Length: %u" pr_err("PRIN SA READ_KEYS SCSI Data Length: %u"
" too small\n", cmd->data_length); " too small\n", cmd->data_length);
return PYX_TRANSPORT_INVALID_CDB_FIELD; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
} }
buf = transport_kmap_first_data_page(cmd); buf = transport_kmap_first_data_page(cmd);
...@@ -3965,7 +4040,8 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) ...@@ -3965,7 +4040,8 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
if (cmd->data_length < 8) { if (cmd->data_length < 8) {
pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u"
" too small\n", cmd->data_length); " too small\n", cmd->data_length);
return PYX_TRANSPORT_INVALID_CDB_FIELD; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
} }
buf = transport_kmap_first_data_page(cmd); buf = transport_kmap_first_data_page(cmd);
...@@ -4047,7 +4123,8 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) ...@@ -4047,7 +4123,8 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
if (cmd->data_length < 6) { if (cmd->data_length < 6) {
pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:"
" %u too small\n", cmd->data_length); " %u too small\n", cmd->data_length);
return PYX_TRANSPORT_INVALID_CDB_FIELD; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
} }
buf = transport_kmap_first_data_page(cmd); buf = transport_kmap_first_data_page(cmd);
...@@ -4108,7 +4185,8 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) ...@@ -4108,7 +4185,8 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
if (cmd->data_length < 8) { if (cmd->data_length < 8) {
pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u"
" too small\n", cmd->data_length); " too small\n", cmd->data_length);
return PYX_TRANSPORT_INVALID_CDB_FIELD; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
} }
buf = transport_kmap_first_data_page(cmd); buf = transport_kmap_first_data_page(cmd);
...@@ -4255,7 +4333,8 @@ int target_scsi3_emulate_pr_in(struct se_task *task) ...@@ -4255,7 +4333,8 @@ int target_scsi3_emulate_pr_in(struct se_task *task)
pr_err("Received PERSISTENT_RESERVE CDB while legacy" pr_err("Received PERSISTENT_RESERVE CDB while legacy"
" SPC-2 reservation is held, returning" " SPC-2 reservation is held, returning"
" RESERVATION_CONFLICT\n"); " RESERVATION_CONFLICT\n");
return PYX_TRANSPORT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EINVAL;
} }
switch (cmd->t_task_cdb[1] & 0x1f) { switch (cmd->t_task_cdb[1] & 0x1f) {
...@@ -4274,7 +4353,8 @@ int target_scsi3_emulate_pr_in(struct se_task *task) ...@@ -4274,7 +4353,8 @@ int target_scsi3_emulate_pr_in(struct se_task *task)
default: default:
pr_err("Unknown PERSISTENT_RESERVE_IN service" pr_err("Unknown PERSISTENT_RESERVE_IN service"
" action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f);
ret = PYX_TRANSPORT_INVALID_CDB_FIELD; cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
ret = -EINVAL;
break; break;
} }
......
...@@ -963,6 +963,7 @@ static inline struct bio *pscsi_get_bio(int sg_num) ...@@ -963,6 +963,7 @@ static inline struct bio *pscsi_get_bio(int sg_num)
static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg,
struct bio **hbio) struct bio **hbio)
{ {
struct se_cmd *cmd = task->task_se_cmd;
struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr;
u32 task_sg_num = task->task_sg_nents; u32 task_sg_num = task->task_sg_nents;
struct bio *bio = NULL, *tbio = NULL; struct bio *bio = NULL, *tbio = NULL;
...@@ -971,7 +972,7 @@ static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, ...@@ -971,7 +972,7 @@ static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg,
u32 data_len = task->task_size, i, len, bytes, off; u32 data_len = task->task_size, i, len, bytes, off;
int nr_pages = (task->task_size + task_sg[0].offset + int nr_pages = (task->task_size + task_sg[0].offset +
PAGE_SIZE - 1) >> PAGE_SHIFT; PAGE_SIZE - 1) >> PAGE_SHIFT;
int nr_vecs = 0, rc, ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; int nr_vecs = 0, rc;
int rw = (task->task_data_direction == DMA_TO_DEVICE); int rw = (task->task_data_direction == DMA_TO_DEVICE);
*hbio = NULL; *hbio = NULL;
...@@ -1058,11 +1059,13 @@ static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, ...@@ -1058,11 +1059,13 @@ static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg,
bio->bi_next = NULL; bio->bi_next = NULL;
bio_endio(bio, 0); /* XXX: should be error */ bio_endio(bio, 0); /* XXX: should be error */
} }
return ret; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -ENOMEM;
} }
static int pscsi_do_task(struct se_task *task) static int pscsi_do_task(struct se_task *task)
{ {
struct se_cmd *cmd = task->task_se_cmd;
struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr;
struct pscsi_plugin_task *pt = PSCSI_TASK(task); struct pscsi_plugin_task *pt = PSCSI_TASK(task);
struct request *req; struct request *req;
...@@ -1078,7 +1081,9 @@ static int pscsi_do_task(struct se_task *task) ...@@ -1078,7 +1081,9 @@ static int pscsi_do_task(struct se_task *task)
if (!req || IS_ERR(req)) { if (!req || IS_ERR(req)) {
pr_err("PSCSI: blk_get_request() failed: %ld\n", pr_err("PSCSI: blk_get_request() failed: %ld\n",
req ? IS_ERR(req) : -ENOMEM); req ? IS_ERR(req) : -ENOMEM);
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason =
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -ENODEV;
} }
} else { } else {
BUG_ON(!task->task_size); BUG_ON(!task->task_size);
...@@ -1087,8 +1092,11 @@ static int pscsi_do_task(struct se_task *task) ...@@ -1087,8 +1092,11 @@ static int pscsi_do_task(struct se_task *task)
* Setup the main struct request for the task->task_sg[] payload * Setup the main struct request for the task->task_sg[] payload
*/ */
ret = pscsi_map_sg(task, task->task_sg, &hbio); ret = pscsi_map_sg(task, task->task_sg, &hbio);
if (ret < 0) if (ret < 0) {
return PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason =
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return ret;
}
req = blk_make_request(pdv->pdv_sd->request_queue, hbio, req = blk_make_request(pdv->pdv_sd->request_queue, hbio,
GFP_KERNEL); GFP_KERNEL);
...@@ -1115,7 +1123,7 @@ static int pscsi_do_task(struct se_task *task) ...@@ -1115,7 +1123,7 @@ static int pscsi_do_task(struct se_task *task)
(task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG), (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG),
pscsi_req_done); pscsi_req_done);
return PYX_TRANSPORT_SENT_TO_TRANSPORT; return 0;
fail: fail:
while (hbio) { while (hbio) {
...@@ -1124,7 +1132,8 @@ static int pscsi_do_task(struct se_task *task) ...@@ -1124,7 +1132,8 @@ static int pscsi_do_task(struct se_task *task)
bio->bi_next = NULL; bio->bi_next = NULL;
bio_endio(bio, 0); /* XXX: should be error */ bio_endio(bio, 0); /* XXX: should be error */
} }
return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -ENOMEM;
} }
/* pscsi_get_sense_buffer(): /* pscsi_get_sense_buffer():
...@@ -1198,9 +1207,8 @@ static inline void pscsi_process_SAM_status( ...@@ -1198,9 +1207,8 @@ static inline void pscsi_process_SAM_status(
" 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0], " 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0],
pt->pscsi_result); pt->pscsi_result);
task->task_scsi_status = SAM_STAT_CHECK_CONDITION; task->task_scsi_status = SAM_STAT_CHECK_CONDITION;
task->task_error_status = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; task->task_se_cmd->scsi_sense_reason =
task->task_se_cmd->transport_error_status = TCM_UNSUPPORTED_SCSI_OPCODE;
PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
transport_complete_task(task, 0); transport_complete_task(task, 0);
break; break;
} }
......
...@@ -603,8 +603,7 @@ static int rd_MEMCPY_do_task(struct se_task *task) ...@@ -603,8 +603,7 @@ static int rd_MEMCPY_do_task(struct se_task *task)
task->task_scsi_status = GOOD; task->task_scsi_status = GOOD;
transport_complete_task(task, 1); transport_complete_task(task, 1);
return 0;
return PYX_TRANSPORT_SENT_TO_TRANSPORT;
} }
/* rd_free_task(): (Part of se_subsystem_api_t template) /* rd_free_task(): (Part of se_subsystem_api_t template)
......
...@@ -345,10 +345,6 @@ static void core_tmr_drain_cmd_list( ...@@ -345,10 +345,6 @@ static void core_tmr_drain_cmd_list(
" %d t_fe_count: %d\n", (preempt_and_abort_list) ? " %d t_fe_count: %d\n", (preempt_and_abort_list) ?
"Preempt" : "", cmd, cmd->t_state, "Preempt" : "", cmd, cmd->t_state,
atomic_read(&cmd->t_fe_count)); atomic_read(&cmd->t_fe_count));
/*
* Signal that the command has failed via cmd->se_cmd_flags,
*/
transport_new_cmd_failure(cmd);
core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, core_tmr_handle_tas_abort(tmr_nacl, cmd, tas,
atomic_read(&cmd->t_fe_count)); atomic_read(&cmd->t_fe_count));
......
...@@ -82,7 +82,7 @@ static int transport_generic_get_mem(struct se_cmd *cmd); ...@@ -82,7 +82,7 @@ static int transport_generic_get_mem(struct se_cmd *cmd);
static void transport_put_cmd(struct se_cmd *cmd); static void transport_put_cmd(struct se_cmd *cmd);
static void transport_remove_cmd_from_queue(struct se_cmd *cmd); static void transport_remove_cmd_from_queue(struct se_cmd *cmd);
static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq); static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq);
static void transport_generic_request_failure(struct se_cmd *, int, int); static void transport_generic_request_failure(struct se_cmd *);
static void target_complete_ok_work(struct work_struct *work); static void target_complete_ok_work(struct work_struct *work);
int init_se_kmem_caches(void) int init_se_kmem_caches(void)
...@@ -680,9 +680,9 @@ void transport_complete_sync_cache(struct se_cmd *cmd, int good) ...@@ -680,9 +680,9 @@ void transport_complete_sync_cache(struct se_cmd *cmd, int good)
task->task_scsi_status = GOOD; task->task_scsi_status = GOOD;
} else { } else {
task->task_scsi_status = SAM_STAT_CHECK_CONDITION; task->task_scsi_status = SAM_STAT_CHECK_CONDITION;
task->task_error_status = PYX_TRANSPORT_ILLEGAL_REQUEST; task->task_se_cmd->scsi_sense_reason =
task->task_se_cmd->transport_error_status = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
PYX_TRANSPORT_ILLEGAL_REQUEST;
} }
transport_complete_task(task, good); transport_complete_task(task, good);
...@@ -693,7 +693,7 @@ static void target_complete_failure_work(struct work_struct *work) ...@@ -693,7 +693,7 @@ static void target_complete_failure_work(struct work_struct *work)
{ {
struct se_cmd *cmd = container_of(work, struct se_cmd, work); struct se_cmd *cmd = container_of(work, struct se_cmd, work);
transport_generic_request_failure(cmd, 1, 1); transport_generic_request_failure(cmd);
} }
/* transport_complete_task(): /* transport_complete_task():
...@@ -755,10 +755,11 @@ void transport_complete_task(struct se_task *task, int success) ...@@ -755,10 +755,11 @@ void transport_complete_task(struct se_task *task, int success)
if (cmd->t_tasks_failed) { if (cmd->t_tasks_failed) {
if (!task->task_error_status) { if (!task->task_error_status) {
task->task_error_status = task->task_error_status =
PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
cmd->transport_error_status = cmd->scsi_sense_reason =
PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
} }
INIT_WORK(&cmd->work, target_complete_failure_work); INIT_WORK(&cmd->work, target_complete_failure_work);
} else { } else {
atomic_set(&cmd->t_transport_complete, 1); atomic_set(&cmd->t_transport_complete, 1);
...@@ -1573,6 +1574,8 @@ int transport_generic_allocate_tasks( ...@@ -1573,6 +1574,8 @@ int transport_generic_allocate_tasks(
pr_err("Received SCSI CDB with command_size: %d that" pr_err("Received SCSI CDB with command_size: %d that"
" exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n",
scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE); scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE);
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL; return -EINVAL;
} }
/* /*
...@@ -1588,6 +1591,9 @@ int transport_generic_allocate_tasks( ...@@ -1588,6 +1591,9 @@ int transport_generic_allocate_tasks(
" %u > sizeof(cmd->__t_task_cdb): %lu ops\n", " %u > sizeof(cmd->__t_task_cdb): %lu ops\n",
scsi_command_size(cdb), scsi_command_size(cdb),
(unsigned long)sizeof(cmd->__t_task_cdb)); (unsigned long)sizeof(cmd->__t_task_cdb));
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->scsi_sense_reason =
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -ENOMEM; return -ENOMEM;
} }
} else } else
...@@ -1658,11 +1664,9 @@ int transport_handle_cdb_direct( ...@@ -1658,11 +1664,9 @@ int transport_handle_cdb_direct(
* and call transport_generic_request_failure() if necessary.. * and call transport_generic_request_failure() if necessary..
*/ */
ret = transport_generic_new_cmd(cmd); ret = transport_generic_new_cmd(cmd);
if (ret < 0) { if (ret < 0)
cmd->transport_error_status = ret; transport_generic_request_failure(cmd);
transport_generic_request_failure(cmd, 0,
(cmd->data_direction != DMA_TO_DEVICE));
}
return 0; return 0;
} }
EXPORT_SYMBOL(transport_handle_cdb_direct); EXPORT_SYMBOL(transport_handle_cdb_direct);
...@@ -1798,20 +1802,16 @@ static int transport_stop_tasks_for_cmd(struct se_cmd *cmd) ...@@ -1798,20 +1802,16 @@ static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
/* /*
* Handle SAM-esque emulation for generic transport request failures. * Handle SAM-esque emulation for generic transport request failures.
*/ */
static void transport_generic_request_failure( static void transport_generic_request_failure(struct se_cmd *cmd)
struct se_cmd *cmd,
int complete,
int sc)
{ {
int ret = 0; int ret = 0;
pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x"
" CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd),
cmd->t_task_cdb[0]); cmd->t_task_cdb[0]);
pr_debug("-----[ i_state: %d t_state: %d transport_error_status: %d\n", pr_debug("-----[ i_state: %d t_state: %d scsi_sense_reason: %d\n",
cmd->se_tfo->get_cmd_state(cmd), cmd->se_tfo->get_cmd_state(cmd),
cmd->t_state, cmd->t_state, cmd->scsi_sense_reason);
cmd->transport_error_status);
pr_debug("-----[ t_tasks: %d t_task_cdbs_left: %d" pr_debug("-----[ t_tasks: %d t_task_cdbs_left: %d"
" t_task_cdbs_sent: %d t_task_cdbs_ex_left: %d --" " t_task_cdbs_sent: %d t_task_cdbs_ex_left: %d --"
" t_transport_active: %d t_transport_stop: %d" " t_transport_active: %d t_transport_stop: %d"
...@@ -1829,46 +1829,19 @@ static void transport_generic_request_failure( ...@@ -1829,46 +1829,19 @@ static void transport_generic_request_failure(
if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED)
transport_complete_task_attr(cmd); transport_complete_task_attr(cmd);
if (complete) { switch (cmd->scsi_sense_reason) {
cmd->transport_error_status = PYX_TRANSPORT_LU_COMM_FAILURE; case TCM_NON_EXISTENT_LUN:
} case TCM_UNSUPPORTED_SCSI_OPCODE:
case TCM_INVALID_CDB_FIELD:
switch (cmd->transport_error_status) { case TCM_INVALID_PARAMETER_LIST:
case PYX_TRANSPORT_UNKNOWN_SAM_OPCODE: case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE:
cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; case TCM_UNKNOWN_MODE_PAGE:
break; case TCM_WRITE_PROTECTED:
case PYX_TRANSPORT_REQ_TOO_MANY_SECTORS: case TCM_CHECK_CONDITION_ABORT_CMD:
cmd->scsi_sense_reason = TCM_SECTOR_COUNT_TOO_MANY; case TCM_CHECK_CONDITION_UNIT_ATTENTION:
break; case TCM_CHECK_CONDITION_NOT_READY:
case PYX_TRANSPORT_INVALID_CDB_FIELD:
cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
break;
case PYX_TRANSPORT_INVALID_PARAMETER_LIST:
cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
break;
case PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES:
if (!sc)
transport_new_cmd_failure(cmd);
/*
* Currently for PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES,
* we force this session to fall back to session
* recovery.
*/
cmd->se_tfo->fall_back_to_erl0(cmd->se_sess);
cmd->se_tfo->stop_session(cmd->se_sess, 0, 0);
goto check_stop;
case PYX_TRANSPORT_LU_COMM_FAILURE:
case PYX_TRANSPORT_ILLEGAL_REQUEST:
cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
break;
case PYX_TRANSPORT_UNKNOWN_MODE_PAGE:
cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE;
break;
case PYX_TRANSPORT_WRITE_PROTECTED:
cmd->scsi_sense_reason = TCM_WRITE_PROTECTED;
break; break;
case PYX_TRANSPORT_RESERVATION_CONFLICT: case TCM_RESERVATION_CONFLICT:
/* /*
* No SENSE Data payload for this case, set SCSI Status * No SENSE Data payload for this case, set SCSI Status
* and queue the response to $FABRIC_MOD. * and queue the response to $FABRIC_MOD.
...@@ -1893,15 +1866,9 @@ static void transport_generic_request_failure( ...@@ -1893,15 +1866,9 @@ static void transport_generic_request_failure(
if (ret == -EAGAIN || ret == -ENOMEM) if (ret == -EAGAIN || ret == -ENOMEM)
goto queue_full; goto queue_full;
goto check_stop; goto check_stop;
case PYX_TRANSPORT_USE_SENSE_REASON:
/*
* struct se_cmd->scsi_sense_reason already set
*/
break;
default: default:
pr_err("Unknown transport error for CDB 0x%02x: %d\n", pr_err("Unknown transport error for CDB 0x%02x: %d\n",
cmd->t_task_cdb[0], cmd->t_task_cdb[0], cmd->scsi_sense_reason);
cmd->transport_error_status);
cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
break; break;
} }
...@@ -1912,14 +1879,10 @@ static void transport_generic_request_failure( ...@@ -1912,14 +1879,10 @@ static void transport_generic_request_failure(
* transport_send_check_condition_and_sense() after handling * transport_send_check_condition_and_sense() after handling
* possible unsoliticied write data payloads. * possible unsoliticied write data payloads.
*/ */
if (!sc && !cmd->se_tfo->new_cmd_map) ret = transport_send_check_condition_and_sense(cmd,
transport_new_cmd_failure(cmd); cmd->scsi_sense_reason, 0);
else { if (ret == -EAGAIN || ret == -ENOMEM)
ret = transport_send_check_condition_and_sense(cmd, goto queue_full;
cmd->scsi_sense_reason, 0);
if (ret == -EAGAIN || ret == -ENOMEM)
goto queue_full;
}
check_stop: check_stop:
transport_lun_remove_cmd(cmd); transport_lun_remove_cmd(cmd);
...@@ -2077,8 +2040,8 @@ static int transport_execute_tasks(struct se_cmd *cmd) ...@@ -2077,8 +2040,8 @@ static int transport_execute_tasks(struct se_cmd *cmd)
int add_tasks; int add_tasks;
if (se_dev_check_online(cmd->se_orig_obj_ptr) != 0) { if (se_dev_check_online(cmd->se_orig_obj_ptr) != 0) {
cmd->transport_error_status = PYX_TRANSPORT_LU_COMM_FAILURE; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
transport_generic_request_failure(cmd, 0, 1); transport_generic_request_failure(cmd);
return 0; return 0;
} }
...@@ -2163,14 +2126,13 @@ static int __transport_execute_tasks(struct se_device *dev) ...@@ -2163,14 +2126,13 @@ static int __transport_execute_tasks(struct se_device *dev)
else else
error = dev->transport->do_task(task); error = dev->transport->do_task(task);
if (error != 0) { if (error != 0) {
cmd->transport_error_status = error;
spin_lock_irqsave(&cmd->t_state_lock, flags); spin_lock_irqsave(&cmd->t_state_lock, flags);
task->task_flags &= ~TF_ACTIVE; task->task_flags &= ~TF_ACTIVE;
spin_unlock_irqrestore(&cmd->t_state_lock, flags); spin_unlock_irqrestore(&cmd->t_state_lock, flags);
atomic_set(&cmd->t_transport_sent, 0); atomic_set(&cmd->t_transport_sent, 0);
transport_stop_tasks_for_cmd(cmd); transport_stop_tasks_for_cmd(cmd);
atomic_inc(&dev->depth_left); atomic_inc(&dev->depth_left);
transport_generic_request_failure(cmd, 0, 1); transport_generic_request_failure(cmd);
} }
goto check_depth; goto check_depth;
...@@ -2178,19 +2140,6 @@ static int __transport_execute_tasks(struct se_device *dev) ...@@ -2178,19 +2140,6 @@ static int __transport_execute_tasks(struct se_device *dev)
return 0; return 0;
} }
void transport_new_cmd_failure(struct se_cmd *se_cmd)
{
unsigned long flags;
/*
* Any unsolicited data will get dumped for failed command inside of
* the fabric plugin
*/
spin_lock_irqsave(&se_cmd->t_state_lock, flags);
se_cmd->se_cmd_flags |= SCF_SE_CMD_FAILED;
se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
}
static inline u32 transport_get_sectors_6( static inline u32 transport_get_sectors_6(
unsigned char *cdb, unsigned char *cdb,
struct se_cmd *cmd, struct se_cmd *cmd,
...@@ -2460,27 +2409,6 @@ static int transport_get_sense_data(struct se_cmd *cmd) ...@@ -2460,27 +2409,6 @@ static int transport_get_sense_data(struct se_cmd *cmd)
return -1; return -1;
} }
static int
transport_handle_reservation_conflict(struct se_cmd *cmd)
{
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT;
cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
/*
* For UA Interlock Code 11b, a RESERVATION CONFLICT will
* establish a UNIT ATTENTION with PREVIOUS RESERVATION
* CONFLICT STATUS.
*
* See spc4r17, section 7.4.6 Control Mode Page, Table 349
*/
if (cmd->se_sess &&
cmd->se_dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 2)
core_scsi3_ua_allocate(cmd->se_sess->se_node_acl,
cmd->orig_fe_lun, 0x2C,
ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS);
return -EINVAL;
}
static inline long long transport_dev_end_lba(struct se_device *dev) static inline long long transport_dev_end_lba(struct se_device *dev)
{ {
return dev->transport->get_blocks(dev) + 1; return dev->transport->get_blocks(dev) + 1;
...@@ -2595,8 +2523,12 @@ static int transport_generic_cmd_sequencer( ...@@ -2595,8 +2523,12 @@ static int transport_generic_cmd_sequencer(
*/ */
if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type) != 0) { if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type) != 0) {
if (su_dev->t10_pr.pr_ops.t10_seq_non_holder( if (su_dev->t10_pr.pr_ops.t10_seq_non_holder(
cmd, cdb, pr_reg_type) != 0) cmd, cdb, pr_reg_type) != 0) {
return transport_handle_reservation_conflict(cmd); cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT;
cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EBUSY;
}
/* /*
* This means the CDB is allowed for the SCSI Initiator port * This means the CDB is allowed for the SCSI Initiator port
* when said port is *NOT* holding the legacy SPC-2 or * when said port is *NOT* holding the legacy SPC-2 or
...@@ -3813,7 +3745,7 @@ int transport_generic_new_cmd(struct se_cmd *cmd) ...@@ -3813,7 +3745,7 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
cmd->data_length) { cmd->data_length) {
ret = transport_generic_get_mem(cmd); ret = transport_generic_get_mem(cmd);
if (ret < 0) if (ret < 0)
return ret; goto out_fail;
} }
/* /*
...@@ -3929,7 +3861,7 @@ static int transport_generic_write_pending(struct se_cmd *cmd) ...@@ -3929,7 +3861,7 @@ static int transport_generic_write_pending(struct se_cmd *cmd)
else if (ret < 0) else if (ret < 0)
return ret; return ret;
return PYX_TRANSPORT_WRITE_PENDING; return 1;
queue_full: queue_full:
pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd);
...@@ -4602,9 +4534,6 @@ void transport_send_task_abort(struct se_cmd *cmd) ...@@ -4602,9 +4534,6 @@ void transport_send_task_abort(struct se_cmd *cmd)
if (cmd->se_tfo->write_pending_status(cmd) != 0) { if (cmd->se_tfo->write_pending_status(cmd) != 0) {
atomic_inc(&cmd->t_transport_aborted); atomic_inc(&cmd->t_transport_aborted);
smp_mb__after_atomic_inc(); smp_mb__after_atomic_inc();
cmd->scsi_status = SAM_STAT_TASK_ABORTED;
transport_new_cmd_failure(cmd);
return;
} }
} }
cmd->scsi_status = SAM_STAT_TASK_ABORTED; cmd->scsi_status = SAM_STAT_TASK_ABORTED;
...@@ -4698,18 +4627,13 @@ static int transport_processing_thread(void *param) ...@@ -4698,18 +4627,13 @@ static int transport_processing_thread(void *param)
} }
ret = cmd->se_tfo->new_cmd_map(cmd); ret = cmd->se_tfo->new_cmd_map(cmd);
if (ret < 0) { if (ret < 0) {
cmd->transport_error_status = ret; transport_generic_request_failure(cmd);
transport_generic_request_failure(cmd,
0, (cmd->data_direction !=
DMA_TO_DEVICE));
break; break;
} }
ret = transport_generic_new_cmd(cmd); ret = transport_generic_new_cmd(cmd);
if (ret < 0) { if (ret < 0) {
cmd->transport_error_status = ret; transport_generic_request_failure(cmd);
transport_generic_request_failure(cmd, break;
0, (cmd->data_direction !=
DMA_TO_DEVICE));
} }
break; break;
case TRANSPORT_PROCESS_WRITE: case TRANSPORT_PROCESS_WRITE:
......
...@@ -200,7 +200,7 @@ int ft_write_pending(struct se_cmd *se_cmd) ...@@ -200,7 +200,7 @@ int ft_write_pending(struct se_cmd *se_cmd)
lport = ep->lp; lport = ep->lp;
fp = fc_frame_alloc(lport, sizeof(*txrdy)); fp = fc_frame_alloc(lport, sizeof(*txrdy));
if (!fp) if (!fp)
return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; return -ENOMEM; /* Signal QUEUE_FULL */
txrdy = fc_frame_payload_get(fp, sizeof(*txrdy)); txrdy = fc_frame_payload_get(fp, sizeof(*txrdy));
memset(txrdy, 0, sizeof(*txrdy)); memset(txrdy, 0, sizeof(*txrdy));
......
...@@ -103,7 +103,6 @@ enum se_cmd_flags_table { ...@@ -103,7 +103,6 @@ enum se_cmd_flags_table {
SCF_SCSI_NON_DATA_CDB = 0x00000040, SCF_SCSI_NON_DATA_CDB = 0x00000040,
SCF_SCSI_CDB_EXCEPTION = 0x00000080, SCF_SCSI_CDB_EXCEPTION = 0x00000080,
SCF_SCSI_RESERVATION_CONFLICT = 0x00000100, SCF_SCSI_RESERVATION_CONFLICT = 0x00000100,
SCF_SE_CMD_FAILED = 0x00000400,
SCF_SE_LUN_CMD = 0x00000800, SCF_SE_LUN_CMD = 0x00000800,
SCF_SE_ALLOW_EOO = 0x00001000, SCF_SE_ALLOW_EOO = 0x00001000,
SCF_SENT_CHECK_CONDITION = 0x00004000, SCF_SENT_CHECK_CONDITION = 0x00004000,
...@@ -154,6 +153,7 @@ enum tcm_sense_reason_table { ...@@ -154,6 +153,7 @@ enum tcm_sense_reason_table {
TCM_CHECK_CONDITION_ABORT_CMD = 0x0d, TCM_CHECK_CONDITION_ABORT_CMD = 0x0d,
TCM_CHECK_CONDITION_UNIT_ATTENTION = 0x0e, TCM_CHECK_CONDITION_UNIT_ATTENTION = 0x0e,
TCM_CHECK_CONDITION_NOT_READY = 0x0f, TCM_CHECK_CONDITION_NOT_READY = 0x0f,
TCM_RESERVATION_CONFLICT = 0x10,
}; };
struct se_obj { struct se_obj {
...@@ -422,8 +422,6 @@ struct se_cmd { ...@@ -422,8 +422,6 @@ struct se_cmd {
int sam_task_attr; int sam_task_attr;
/* Transport protocol dependent state, see transport_state_table */ /* Transport protocol dependent state, see transport_state_table */
enum transport_state_table t_state; enum transport_state_table t_state;
/* Transport specific error status */
int transport_error_status;
/* Used to signal cmd->se_tfo->check_release_cmd() usage per cmd */ /* Used to signal cmd->se_tfo->check_release_cmd() usage per cmd */
int check_release:1; int check_release:1;
int cmd_wait_set:1; int cmd_wait_set:1;
......
...@@ -10,29 +10,6 @@ ...@@ -10,29 +10,6 @@
#define PYX_TRANSPORT_STATUS_INTERVAL 5 /* In seconds */ #define PYX_TRANSPORT_STATUS_INTERVAL 5 /* In seconds */
#define PYX_TRANSPORT_SENT_TO_TRANSPORT 0
#define PYX_TRANSPORT_WRITE_PENDING 1
#define PYX_TRANSPORT_UNKNOWN_SAM_OPCODE -1
#define PYX_TRANSPORT_HBA_QUEUE_FULL -2
#define PYX_TRANSPORT_REQ_TOO_MANY_SECTORS -3
#define PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES -4
#define PYX_TRANSPORT_INVALID_CDB_FIELD -5
#define PYX_TRANSPORT_INVALID_PARAMETER_LIST -6
#define PYX_TRANSPORT_LU_COMM_FAILURE -7
#define PYX_TRANSPORT_UNKNOWN_MODE_PAGE -8
#define PYX_TRANSPORT_WRITE_PROTECTED -9
#define PYX_TRANSPORT_RESERVATION_CONFLICT -10
#define PYX_TRANSPORT_ILLEGAL_REQUEST -11
#define PYX_TRANSPORT_USE_SENSE_REASON -12
#ifndef SAM_STAT_RESERVATION_CONFLICT
#define SAM_STAT_RESERVATION_CONFLICT 0x18
#endif
#define TRANSPORT_PLUGIN_FREE 0
#define TRANSPORT_PLUGIN_REGISTERED 1
#define TRANSPORT_PLUGIN_PHBA_PDEV 1 #define TRANSPORT_PLUGIN_PHBA_PDEV 1
#define TRANSPORT_PLUGIN_VHBA_PDEV 2 #define TRANSPORT_PLUGIN_VHBA_PDEV 2
#define TRANSPORT_PLUGIN_VHBA_VDEV 3 #define TRANSPORT_PLUGIN_VHBA_VDEV 3
...@@ -158,7 +135,6 @@ extern int transport_generic_allocate_tasks(struct se_cmd *, unsigned char *); ...@@ -158,7 +135,6 @@ extern int transport_generic_allocate_tasks(struct se_cmd *, unsigned char *);
extern int transport_handle_cdb_direct(struct se_cmd *); extern int transport_handle_cdb_direct(struct se_cmd *);
extern int transport_generic_handle_cdb_map(struct se_cmd *); extern int transport_generic_handle_cdb_map(struct se_cmd *);
extern int transport_generic_handle_data(struct se_cmd *); extern int transport_generic_handle_data(struct se_cmd *);
extern void transport_new_cmd_failure(struct se_cmd *);
extern int transport_generic_handle_tmr(struct se_cmd *); extern int transport_generic_handle_tmr(struct se_cmd *);
extern bool target_stop_task(struct se_task *task, unsigned long *flags); extern bool target_stop_task(struct se_task *task, unsigned long *flags);
extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32, extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment