summaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_cdb.c
diff options
context:
space:
mode:
authorChristoph Hellwig2011-11-03 22:50:44 +0100
committerNicholas Bellinger2011-11-04 11:43:35 +0100
commitd29a5b6acc4b63d4e05ff554509df6fbeaf527cd (patch)
treeedd94dc0420982dea35a811827757b3145689df0 /drivers/target/target_core_cdb.c
parenttarget: refactor transport_emulate_control_cdb (diff)
downloadkernel-qcow2-linux-d29a5b6acc4b63d4e05ff554509df6fbeaf527cd.tar.gz
kernel-qcow2-linux-d29a5b6acc4b63d4e05ff554509df6fbeaf527cd.tar.xz
kernel-qcow2-linux-d29a5b6acc4b63d4e05ff554509df6fbeaf527cd.zip
target: remove SCF_EMULATE_CDB_ASYNC
All ->execute_task instances now need to complete the I/O explicitly, which can either happen synchronously or asynchronously. Note that a lot of the CDB emulations appear to return success even if some lowlevel operations failed. Given that this is an existing issue this patch doesn't change that fact. (nab: Adding missing switch breaks in PR-IN + PR_OUT) Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/target_core_cdb.c')
-rw-r--r--drivers/target/target_core_cdb.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
index ff2dfa383735..5a03085304e5 100644
--- a/drivers/target/target_core_cdb.c
+++ b/drivers/target/target_core_cdb.c
@@ -688,8 +688,10 @@ target_emulate_inquiry(struct se_task *task)
unsigned char *cdb = cmd->t_task_cdb;
int p, ret;
- if (!(cdb[1] & 0x1))
- return target_emulate_inquiry_std(cmd);
+ if (!(cdb[1] & 0x1)) {
+ ret = target_emulate_inquiry_std(cmd);
+ goto out;
+ }
/*
* Make sure we at least have 4 bytes of INQUIRY response
@@ -708,17 +710,25 @@ target_emulate_inquiry(struct se_task *task)
buf[0] = dev->transport->get_device_type(dev);
- for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p)
+ for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) {
if (cdb[2] == evpd_handlers[p].page) {
buf[1] = cdb[2];
ret = evpd_handlers[p].emulate(cmd, buf);
- transport_kunmap_first_data_page(cmd);
- return ret;
+ goto out_unmap;
}
+ }
- transport_kunmap_first_data_page(cmd);
pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]);
- return -EINVAL;
+ ret = -EINVAL;
+
+out_unmap:
+ transport_kunmap_first_data_page(cmd);
+out:
+ if (!ret) {
+ task->task_scsi_status = GOOD;
+ transport_complete_task(task, 1);
+ }
+ return ret;
}
static int
@@ -753,6 +763,8 @@ target_emulate_readcapacity(struct se_task *task)
transport_kunmap_first_data_page(cmd);
+ task->task_scsi_status = GOOD;
+ transport_complete_task(task, 1);
return 0;
}
@@ -787,6 +799,8 @@ target_emulate_readcapacity_16(struct se_task *task)
transport_kunmap_first_data_page(cmd);
+ task->task_scsi_status = GOOD;
+ transport_complete_task(task, 1);
return 0;
}
@@ -1000,6 +1014,8 @@ target_emulate_modesense(struct se_task *task)
memcpy(rbuf, buf, offset);
transport_kunmap_first_data_page(cmd);
+ task->task_scsi_status = GOOD;
+ transport_complete_task(task, 1);
return 0;
}
@@ -1065,7 +1081,8 @@ target_emulate_request_sense(struct se_task *task)
end:
transport_kunmap_first_data_page(cmd);
-
+ task->task_scsi_status = GOOD;
+ transport_complete_task(task, 1);
return 0;
}
@@ -1122,7 +1139,10 @@ target_emulate_unmap(struct se_task *task)
err:
transport_kunmap_first_data_page(cmd);
-
+ if (!ret) {
+ task->task_scsi_status = GOOD;
+ transport_complete_task(task, 1);
+ }
return ret;
}
@@ -1171,6 +1191,8 @@ target_emulate_write_same(struct se_task *task)
return ret;
}
+ task->task_scsi_status = GOOD;
+ transport_complete_task(task, 1);
return 0;
}
@@ -1189,6 +1211,14 @@ target_emulate_synchronize_cache(struct se_task *task)
return 0;
}
+static int
+target_emulate_noop(struct se_task *task)
+{
+ task->task_scsi_status = GOOD;
+ transport_complete_task(task, 1);
+ return 0;
+}
+
int
transport_emulate_control_cdb(struct se_task *task)
{
@@ -1259,6 +1289,7 @@ transport_emulate_control_cdb(struct se_task *task)
case TEST_UNIT_READY:
case VERIFY:
case WRITE_FILEMARKS:
+ ret = target_emulate_noop(task);
break;
default:
pr_err("Unsupported SCSI Opcode: 0x%02x for %s\n",
@@ -1268,15 +1299,6 @@ transport_emulate_control_cdb(struct se_task *task)
if (ret < 0)
return ret;
- /*
- * Handle the successful completion here unless a caller
- * has explictly requested an asychronous completion.
- */
- if (!(cmd->se_cmd_flags & SCF_EMULATE_CDB_ASYNC)) {
- task->task_scsi_status = GOOD;
- transport_complete_task(task, 1);
- }
-
return PYX_TRANSPORT_SENT_TO_TRANSPORT;
}