diff mbox series

[01/36] target: Handle MI_REPORT_SUPPORTED_OPERATION_CODES

Message ID 118900ffaf094a279f7799ac9d2c73265c889121.1657149962.git.Thinh.Nguyen@synopsys.com
State Superseded
Headers show
Series usb: gadget: f_tcm: Enhance UASP driver | expand

Commit Message

Thinh Nguyen July 6, 2022, 11:34 p.m. UTC
Microsoft Windows checks for MI_REPORT_SUPPORTED_OPERATION_CODES. Let's
handle this MAINTENANCE_IN command and report supported commands.

Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
---
 drivers/target/target_core_alua.c | 66 +++++++++++++++++++++++++++++++
 drivers/target/target_core_alua.h |  2 +
 drivers/target/target_core_spc.c  | 14 ++++++-
 3 files changed, 80 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index b56ef8af66e7..20cfcb70805d 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -259,6 +259,72 @@  target_emulate_report_target_port_groups(struct se_cmd *cmd)
 	return 0;
 }
 
+/*
+ * REPORT_SUPPORTED_OPERATION_CODES
+ *
+ * See spc4r17 section 6.27
+ */
+sense_reason_t
+target_emulate_report_supported_opcodes(struct se_cmd *cmd)
+{
+	unsigned char *cdb = cmd->t_task_cdb;
+	unsigned char *buf;
+	u8 supported = 0;
+
+	if (cdb[2] != 1) {
+		pr_warn("Invalid command format %d\n", cdb[2]);
+		goto out;
+	}
+
+	buf = transport_kmap_data_sg(cmd);
+	if (!buf)
+		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+
+	switch (cdb[3]) {
+	case INQUIRY:
+	case MODE_SENSE:
+	case MODE_SENSE_10:
+	case READ_CAPACITY:
+	case SERVICE_ACTION_IN_16:
+	case REPORT_LUNS:
+	case REQUEST_SENSE:
+	case SYNCHRONIZE_CACHE:
+	case REZERO_UNIT:
+	case SEEK_6:
+	case SEEK_10:
+	case TEST_UNIT_READY:
+	case SEND_DIAGNOSTIC:
+	case MAINTENANCE_IN:
+	case READ_6:
+	case READ_10:
+	case READ_16:
+	case WRITE_6:
+	case WRITE_10:
+	case WRITE_16:
+	case VERIFY_16:
+	case MODE_SELECT:
+	case MODE_SELECT_10:
+	case START_STOP:
+	case SECURITY_PROTOCOL_IN:
+	case SECURITY_PROTOCOL_OUT:
+		supported = 3;
+		break;
+	case ATA_12:
+	case ATA_16:
+	case VERIFY:
+	case ZBC_IN:
+	case ZBC_OUT:
+	default:
+		break;
+	}
+
+	transport_kunmap_data_sg(cmd);
+out:
+	buf[1] = supported;
+	target_complete_cmd(cmd, SAM_STAT_GOOD);
+	return 0;
+}
+
 /*
  * SET_TARGET_PORT_GROUPS for explicit ALUA operation.
  *
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index fc9637cce825..7941e4dd4f97 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -82,6 +82,8 @@  extern struct kmem_cache *t10_alua_tg_pt_gp_cache;
 extern struct kmem_cache *t10_alua_lba_map_cache;
 extern struct kmem_cache *t10_alua_lba_map_mem_cache;
 
+extern sense_reason_t
+target_emulate_report_supported_opcodes(struct se_cmd *cmd);
 extern sense_reason_t target_emulate_report_target_port_groups(struct se_cmd *);
 extern sense_reason_t target_emulate_set_target_port_groups(struct se_cmd *);
 extern sense_reason_t target_emulate_report_referrals(struct se_cmd *);
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index c14441c89bed..dd799158609d 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -1425,15 +1425,25 @@  spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
 		break;
 	case MAINTENANCE_IN:
 		if (dev->transport->get_device_type(dev) != TYPE_ROM) {
+			u8 action = cdb[1] & 0x1f;
+
 			/*
 			 * MAINTENANCE_IN from SCC-2
 			 * Check for emulated MI_REPORT_TARGET_PGS
 			 */
-			if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS) {
+			if (action == MI_REPORT_TARGET_PGS) {
 				cmd->execute_cmd =
 					target_emulate_report_target_port_groups;
+
+				*size = get_unaligned_be32(&cdb[6]);
+			}
+
+			if (action == MI_REPORT_SUPPORTED_OPERATION_CODES) {
+				cmd->execute_cmd =
+					target_emulate_report_supported_opcodes;
+
+				*size = get_unaligned_be16(&cdb[2]);
 			}
-			*size = get_unaligned_be32(&cdb[6]);
 		} else {
 			/*
 			 * GPCMD_SEND_KEY from multi media commands