[PATCH 3/3] SEND-DIAGNOSTICS: implement the minimum required part of this opcode (self-test)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Implement the minimal required part of this opcode.
This opcode is mandatory for sbc and ssc devices but only the SEFT-TEST varient is required.
Return status good for the default self-test.
For all other varients return ILLEGAL-REQUEST/INVALID_FIELD_IN_CDB

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx>
---
 usr/sbc.c |    2 +-
 usr/spc.c |   16 ++++++++++++++++
 usr/spc.h |    1 +
 usr/ssc.c |    2 +-
 4 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/usr/sbc.c b/usr/sbc.c
index b7bff8d..53e785b 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -424,7 +424,7 @@ static struct device_type_template sbc_template = {
 		{sbc_mode_sense, NULL, PR_WE_FA|PR_EA_FA|PR_WE_FN|PR_EA_FN},
 		{spc_start_stop, NULL, PR_SPECIAL},
 		{spc_illegal_op,},
-		{spc_illegal_op,},
+		{spc_send_diagnostics,},
 		{spc_illegal_op,},
 		{spc_illegal_op,},
 
diff --git a/usr/spc.c b/usr/spc.c
index eba4857..8b5ecaa 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -746,6 +746,22 @@ find_service_action(struct service_action *service_action, uint32_t action)
 	return NULL;
 }
 
+int spc_send_diagnostics(int host_no, struct scsi_cmd *cmd)
+{
+	uint16_t asc = ASC_INVALID_FIELD_IN_CDB;
+	uint8_t key = ILLEGAL_REQUEST;
+
+	/* we only support SELF-TEST==1 */
+	if (!(cmd->scb[1] & 0x04))
+		goto sense;
+
+	return SAM_STAT_GOOD;
+sense:
+	scsi_set_in_resid_by_actual(cmd, 0);
+	sense_data_build(cmd, key, asc);
+	return SAM_STAT_CHECK_CONDITION;
+}
+
 /*
  * This is useful for the various commands using the SERVICE ACTION
  * format.
diff --git a/usr/spc.h b/usr/spc.h
index 430a882..3c486b8 100644
--- a/usr/spc.h
+++ b/usr/spc.h
@@ -13,6 +13,7 @@ extern int spc_request_sense(int host_no, struct scsi_cmd *cmd);
 extern int spc_prevent_allow_media_removal(int host_no, struct scsi_cmd *cmd);
 extern int spc_illegal_op(int host_no, struct scsi_cmd *cmd);
 extern int spc_lu_init(struct scsi_lu *lu);
+extern int spc_send_diagnostics(int host_no, struct scsi_cmd *cmd);
 
 typedef int (match_fn_t)(struct scsi_lu *lu, char *params);
 extern int lu_config(struct scsi_lu *lu, char *params, match_fn_t *);
diff --git a/usr/ssc.c b/usr/ssc.c
index 94beda1..b816bd8 100644
--- a/usr/ssc.c
+++ b/usr/ssc.c
@@ -199,7 +199,7 @@ static struct device_type_template ssc_template = {
 		{spc_mode_sense,},
 		{spc_start_stop,},
 		{spc_illegal_op,},
-		{spc_illegal_op,},
+		{spc_send_diagnostics,},
 		{spc_prevent_allow_media_removal,},
 		{spc_illegal_op,},
 
-- 
1.7.3.1

--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux