[PATCH 01/36] target: Handle MI_REPORT_SUPPORTED_OPERATION_CODES

Thinh Nguyen
2022-07-06T23:34:34Z

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