Commit cb4f4d3c authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Nicholas Bellinger

target: move unrelated code out of transport_generic_cmd_sequencer

Move all code not related to cdb parsing from transport_generic_cmd_sequencer
into target_setup_cmd_from_cdb.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 1765fe5e
...@@ -1418,6 +1418,10 @@ int target_setup_cmd_from_cdb( ...@@ -1418,6 +1418,10 @@ int target_setup_cmd_from_cdb(
struct se_cmd *cmd, struct se_cmd *cmd,
unsigned char *cdb) unsigned char *cdb)
{ {
struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
u32 pr_reg_type = 0;
u8 alua_ascq = 0;
unsigned long flags;
int ret; int ret;
transport_generic_prepare_cdb(cdb); transport_generic_prepare_cdb(cdb);
...@@ -1457,6 +1461,58 @@ int target_setup_cmd_from_cdb( ...@@ -1457,6 +1461,58 @@ int target_setup_cmd_from_cdb(
* Copy the original CDB into cmd-> * Copy the original CDB into cmd->
*/ */
memcpy(cmd->t_task_cdb, cdb, scsi_command_size(cdb)); memcpy(cmd->t_task_cdb, cdb, scsi_command_size(cdb));
/*
* Check for an existing UNIT ATTENTION condition
*/
if (core_scsi3_ua_check(cmd, cdb) < 0) {
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->scsi_sense_reason = TCM_CHECK_CONDITION_UNIT_ATTENTION;
return -EINVAL;
}
ret = su_dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq);
if (ret != 0) {
/*
* Set SCSI additional sense code (ASC) to 'LUN Not Accessible';
* The ALUA additional sense code qualifier (ASCQ) is determined
* by the ALUA primary or secondary access state..
*/
if (ret > 0) {
pr_debug("[%s]: ALUA TG Port not available, "
"SenseKey: NOT_READY, ASC/ASCQ: "
"0x04/0x%02x\n",
cmd->se_tfo->get_fabric_name(), alua_ascq);
transport_set_sense_codes(cmd, 0x04, alua_ascq);
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->scsi_sense_reason = TCM_CHECK_CONDITION_NOT_READY;
return -EINVAL;
}
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
}
/*
* Check status for SPC-3 Persistent Reservations
*/
if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type)) {
if (su_dev->t10_pr.pr_ops.t10_seq_non_holder(
cmd, cdb, pr_reg_type) != 0) {
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT;
cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EBUSY;
}
/*
* This means the CDB is allowed for the SCSI Initiator port
* when said port is *NOT* holding the legacy SPC-2 or
* SPC-3 Persistent Reservation.
*/
}
/* /*
* Setup the received CDB based on SCSI defined opcodes and * Setup the received CDB based on SCSI defined opcodes and
* perform unit attention, persistent reservations and ALUA * perform unit attention, persistent reservations and ALUA
...@@ -1466,6 +1522,11 @@ int target_setup_cmd_from_cdb( ...@@ -1466,6 +1522,11 @@ int target_setup_cmd_from_cdb(
ret = transport_generic_cmd_sequencer(cmd, cdb); ret = transport_generic_cmd_sequencer(cmd, cdb);
if (ret < 0) if (ret < 0)
return ret; return ret;
spin_lock_irqsave(&cmd->t_state_lock, flags);
cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE;
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
/* /*
* Check for SAM Task Attribute Emulation * Check for SAM Task Attribute Emulation
*/ */
...@@ -1889,15 +1950,6 @@ static inline unsigned long long transport_lba_64_ext(unsigned char *cdb) ...@@ -1889,15 +1950,6 @@ static inline unsigned long long transport_lba_64_ext(unsigned char *cdb)
return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32; return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32;
} }
static void transport_set_supported_SAM_opcode(struct se_cmd *se_cmd)
{
unsigned long flags;
spin_lock_irqsave(&se_cmd->t_state_lock, flags);
se_cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE;
spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
}
/* /*
* Called from Fabric Module context from transport_execute_tasks() * Called from Fabric Module context from transport_execute_tasks()
* *
...@@ -2370,74 +2422,15 @@ static int target_check_write_same_discard(unsigned char *flags, struct se_devic ...@@ -2370,74 +2422,15 @@ static int target_check_write_same_discard(unsigned char *flags, struct se_devic
return 0; return 0;
} }
/* transport_generic_cmd_sequencer():
*
* Generic Command Sequencer that should work for most DAS transport
* drivers.
*
* Called from target_setup_cmd_from_cdb() in the $FABRIC_MOD
* RX Thread.
*
* FIXME: Need to support other SCSI OPCODES where as well.
*/
static int transport_generic_cmd_sequencer( static int transport_generic_cmd_sequencer(
struct se_cmd *cmd, struct se_cmd *cmd,
unsigned char *cdb) unsigned char *cdb)
{ {
struct se_device *dev = cmd->se_dev; struct se_device *dev = cmd->se_dev;
struct se_subsystem_dev *su_dev = dev->se_sub_dev; struct se_subsystem_dev *su_dev = dev->se_sub_dev;
int ret = 0, sector_ret = 0, passthrough; int sector_ret = 0, passthrough;
u32 sectors = 0, size = 0, pr_reg_type = 0; u32 sectors = 0, size = 0;
u16 service_action; u16 service_action;
u8 alua_ascq = 0;
/*
* Check for an existing UNIT ATTENTION condition
*/
if (core_scsi3_ua_check(cmd, cdb) < 0) {
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->scsi_sense_reason = TCM_CHECK_CONDITION_UNIT_ATTENTION;
return -EINVAL;
}
/*
* Check status of Asymmetric Logical Unit Assignment port
*/
ret = su_dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq);
if (ret != 0) {
/*
* Set SCSI additional sense code (ASC) to 'LUN Not Accessible';
* The ALUA additional sense code qualifier (ASCQ) is determined
* by the ALUA primary or secondary access state..
*/
if (ret > 0) {
pr_debug("[%s]: ALUA TG Port not available,"
" SenseKey: NOT_READY, ASC/ASCQ: 0x04/0x%02x\n",
cmd->se_tfo->get_fabric_name(), alua_ascq);
transport_set_sense_codes(cmd, 0x04, alua_ascq);
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->scsi_sense_reason = TCM_CHECK_CONDITION_NOT_READY;
return -EINVAL;
}
goto out_invalid_cdb_field;
}
/*
* Check status for SPC-3 Persistent Reservations
*/
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(
cmd, cdb, pr_reg_type) != 0) {
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT;
cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
return -EBUSY;
}
/*
* This means the CDB is allowed for the SCSI Initiator port
* when said port is *NOT* holding the legacy SPC-2 or
* SPC-3 Persistent Reservation.
*/
}
/* /*
* If we operate in passthrough mode we skip most CDB emulation and * If we operate in passthrough mode we skip most CDB emulation and
...@@ -2992,7 +2985,7 @@ static int transport_generic_cmd_sequencer( ...@@ -2992,7 +2985,7 @@ static int transport_generic_cmd_sequencer(
* Reject READ_* or WRITE_* with overflow/underflow for * Reject READ_* or WRITE_* with overflow/underflow for
* type SCF_SCSI_DATA_SG_IO_CDB. * type SCF_SCSI_DATA_SG_IO_CDB.
*/ */
if (!ret && (dev->se_sub_dev->se_dev_attrib.block_size != 512)) { if (dev->se_sub_dev->se_dev_attrib.block_size != 512) {
pr_err("Failing OVERFLOW/UNDERFLOW for LBA op" pr_err("Failing OVERFLOW/UNDERFLOW for LBA op"
" CDB on non 512-byte sector setup subsystem" " CDB on non 512-byte sector setup subsystem"
" plugin: %s\n", dev->transport->name); " plugin: %s\n", dev->transport->name);
...@@ -3032,8 +3025,7 @@ static int transport_generic_cmd_sequencer( ...@@ -3032,8 +3025,7 @@ static int transport_generic_cmd_sequencer(
(cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB))) (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)))
goto out_unsupported_cdb; goto out_unsupported_cdb;
transport_set_supported_SAM_opcode(cmd); return 0;
return ret;
out_unsupported_cdb: out_unsupported_cdb:
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
...@@ -3967,10 +3959,7 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) ...@@ -3967,10 +3959,7 @@ bool transport_wait_for_tasks(struct se_cmd *cmd)
spin_unlock_irqrestore(&cmd->t_state_lock, flags); spin_unlock_irqrestore(&cmd->t_state_lock, flags);
return false; return false;
} }
/*
* Only perform a possible wait_for_tasks if SCF_SUPPORTED_SAM_OPCODE
* has been set in transport_set_supported_SAM_opcode().
*/
if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) && if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) &&
!(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) { !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) {
spin_unlock_irqrestore(&cmd->t_state_lock, flags); spin_unlock_irqrestore(&cmd->t_state_lock, flags);
......
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