From: Nicholas Bellinger <nab@linux-iscsi.org>
Date: Wed, 30 May 2012 21:09:10 +0000 (-0700)
Subject: target: Move MAINTENANCE_[IN,OUT] from pscsi_parse_cdb -> spc_parse_cdb
X-Git-Tag: firefly_0821_release~3680^2~2412^2~46
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=eba2ca450526c1aaf2bfd363dffd63b024e80ea7;p=firefly-linux-kernel-4.4.55.git

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>
---

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",