summaryrefslogtreecommitdiff
path: root/drivers/target
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2012-05-30 14:09:10 -0700
committerNicholas Bellinger <nab@linux-iscsi.org>2012-07-16 17:28:40 -0700
commiteba2ca450526c1aaf2bfd363dffd63b024e80ea7 (patch)
treed532bfe908962dcf3fa9c28ad1ff6709e22943cd /drivers/target
parent3d6d72014f16967ca92765040be30f022c5952e6 (diff)
target: Move MAINTENANCE_[IN,OUT] from pscsi_parse_cdb -> spc_parse_cdb
The MAINTENANCE_[IN,OUT] CDB parsing required for generic ALUA emulation needs to be in spc_parse_cdb() to function for virtual TYPE_DISK exports, instead of in backend pscsi_parse_cdb() code used only for passthrough ops. Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_spc.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 96dcb57089f7..4c861de538c9 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -35,6 +35,7 @@
#include <target/target_core_fabric.h>
#include "target_core_internal.h"
+#include "target_core_alua.h"
#include "target_core_pr.h"
#include "target_core_ua.h"
@@ -940,7 +941,8 @@ static int spc_emulate_testunitready(struct se_cmd *cmd)
int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
{
- struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
+ struct se_device *dev = cmd->se_dev;
+ struct se_subsystem_dev *su_dev = dev->se_sub_dev;
unsigned char *cdb = cmd->t_task_cdb;
switch (cdb[0]) {
@@ -1050,6 +1052,44 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
cmd->execute_cmd = spc_emulate_testunitready;
*size = 0;
break;
+ case MAINTENANCE_IN:
+ if (dev->transport->get_device_type(dev) != TYPE_ROM) {
+ /*
+ * MAINTENANCE_IN from SCC-2
+ * Check for emulated MI_REPORT_TARGET_PGS
+ */
+ if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS &&
+ su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
+ cmd->execute_cmd =
+ target_emulate_report_target_port_groups;
+ }
+ *size = get_unaligned_be32(&cdb[6]);
+ } else {
+ /*
+ * GPCMD_SEND_KEY from multi media commands
+ */
+ *size = get_unaligned_be16(&cdb[8]);
+ }
+ break;
+ case MAINTENANCE_OUT:
+ if (dev->transport->get_device_type(dev) != TYPE_ROM) {
+ /*
+ * MAINTENANCE_OUT from SCC-2
+ * Check for emulated MO_SET_TARGET_PGS.
+ */
+ if (cdb[1] == MO_SET_TARGET_PGS &&
+ su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
+ cmd->execute_cmd =
+ target_emulate_set_target_port_groups;
+ }
+ *size = get_unaligned_be32(&cdb[6]);
+ } else {
+ /*
+ * GPCMD_SEND_KEY from multi media commands
+ */
+ *size = get_unaligned_be16(&cdb[8]);
+ }
+ break;
default:
pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode"
" 0x%02x, sending CHECK_CONDITION.\n",