[PATCH v2 1/5] scsi_debug: pinpoint invalid field in sense data

2014-11-24 Thread Douglas Gilbert

Use Sense Key Specific field in the sense data of an ILLEGAL REQUEST
to optionally pinpoint the location of the problem field. This may
be either in the cdb or the associated parameter list.
---
 drivers/scsi/scsi_debug.c | 138 +-
 1 file changed, 88 insertions(+), 50 deletions(-)

Signed-off-by: Douglas Gilbert dgilb...@interlog.com
From e3cded06f31aa46a889664c1ea7df7b8b9b998e7 Mon Sep 17 00:00:00 2001
From: Douglas Gilbert dgilb...@interlog.com
Date: Mon, 24 Nov 2014 20:08:11 -0500
Subject: [PATCH 1/5] pinpoint invalid field in sense data

Use Sense Key Specific field in the sense data of an ILLEGAL REQUEST
to optionally pinpoint the location of the problem field. This may
be either in the cdb or the associated parameter list.
---
 drivers/scsi/scsi_debug.c | 138 +-
 1 file changed, 88 insertions(+), 50 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index ce71b6d..a1bca60 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -63,31 +63,34 @@
 #include sd.h
 #include scsi_logging.h
 
-#define SCSI_DEBUG_VERSION 1.84
-static const char *scsi_debug_version_date = 20140706;
+#define SCSI_DEBUG_VERSION 1.85
+static const char *scsi_debug_version_date = 20141022;
 
 #define MY_NAME scsi_debug
 
 /* Additional Sense Code (ASC) */
 #define NO_ADDITIONAL_SENSE 0x0
 #define LOGICAL_UNIT_NOT_READY 0x4
-#define LOGICAL_UNIT_COMMUNICATION_FAILURE 0x8
 #define UNRECOVERED_READ_ERR 0x11
 #define PARAMETER_LIST_LENGTH_ERR 0x1a
 #define INVALID_OPCODE 0x20
-#define ADDR_OUT_OF_RANGE 0x21
 #define INVALID_COMMAND_OPCODE 0x20
+#define LBA_OUT_OF_RANGE 0x21
 #define INVALID_FIELD_IN_CDB 0x24
 #define INVALID_FIELD_IN_PARAM_LIST 0x26
 #define UA_RESET_ASC 0x29
 #define UA_CHANGED_ASC 0x2a
+#define INSUFF_RES_ASC 0x55
+#define INSUFF_RES_ASCQ 0x3
 #define POWER_ON_RESET_ASCQ 0x0
 #define BUS_RESET_ASCQ 0x2	/* scsi bus reset occurred */
 #define MODE_CHANGED_ASCQ 0x1	/* mode parameters changed */
+#define CAPACITY_CHANGED_ASCQ 0x9
 #define SAVING_PARAMS_UNSUP 0x39
 #define TRANSPORT_PROBLEM 0x4b
 #define THRESHOLD_EXCEEDED 0x5d
 #define LOW_POWER_COND_ON 0x5e
+#define MISCOMPARE_VERIFY_ASC 0x1d
 
 /* Additional Sense Code Qualifier (ASCQ) */
 #define ACK_NAK_TO 0x3
@@ -394,6 +397,50 @@ static void sdebug_max_tgts_luns(void)
 	spin_unlock(sdebug_host_list_lock);
 }
 
+enum sdeb_cmd_data {SDEB_IN_DATA = 0, SDEB_IN_CDB = 1};
+
+/* Set in_bit to -1 to indicate no bit position of invalid field */
+static void
+mk_sense_invalid_fld(struct scsi_cmnd *scp, enum sdeb_cmd_data c_d,
+		 int in_byte, int in_bit)
+{
+	unsigned char *sbuff;
+	u8 sks[4];
+	int sl, asc;
+
+	sbuff = scp-sense_buffer;
+	if (!sbuff) {
+		sdev_printk(KERN_ERR, scp-device,
+			%s: sense_buffer is NULL\n, __func__);
+		return;
+	}
+	asc = c_d ? INVALID_FIELD_IN_CDB : INVALID_FIELD_IN_PARAM_LIST;
+	memset(sbuff, 0, SCSI_SENSE_BUFFERSIZE);
+	scsi_build_sense_buffer(scsi_debug_dsense, sbuff, ILLEGAL_REQUEST,
+asc, 0);
+	memset(sks, 0, sizeof(sks));
+	sks[0] = 0x80;
+	if (c_d)
+		sks[0] |= 0x40;
+	if (in_bit = 0) {
+		sks[0] |= 0x8;
+		sks[0] |= 0x7  in_bit;
+	}
+	put_unaligned_be16(in_byte, sks + 1);
+	if (scsi_debug_dsense) {
+		sl = sbuff[7] + 8;
+		sbuff[7] = sl;
+		sbuff[sl] = 0x2;
+		sbuff[sl + 1] = 0x6;
+		memcpy(sbuff + sl + 4, sks, 3);
+	} else
+		memcpy(sbuff + 15, sks, 3);
+	if (SCSI_DEBUG_OPT_NOISE  scsi_debug_opts)
+		sdev_printk(KERN_INFO, scp-device, %s:  [sense_key,asc,ascq
+			]: [0x5,0x%x,0x0] %c byte=%d, bit=%d\n,
+			my_name, asc, c_d ? 'C' : 'D', in_byte, in_bit);
+}
+
 static void mk_sense_buffer(struct scsi_cmnd *scp, int key, int asc, int asq)
 {
 	unsigned char *sbuff;
@@ -414,6 +461,12 @@ static void mk_sense_buffer(struct scsi_cmnd *scp, int key, int asc, int asq)
 			my_name, key, asc, asq);
 }
 
+static void
+mk_sense_invalid_opcode(struct scsi_cmnd *scp)
+{
+	mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_OPCODE, 0);
+}
+
 static void get_data_transfer_info(unsigned char *cmd,
    unsigned long long *lba, unsigned int *num,
    u32 *ei_lba)
@@ -944,8 +997,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, int target,
 		pq_pdt = (scsi_debug_ptype  0x1f);
 	arr[0] = pq_pdt;
 	if (0x2  cmd[1]) {  /* CMDDT bit set */
-		mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
-			   	0);
+		mk_sense_invalid_fld(scp, SDEB_IN_CDB, 1, 1);
 		kfree(arr);
 		return check_condition_result;
 	} else if (0x1  cmd[1]) {  /* EVPD bit set */
@@ -1029,9 +1081,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, int target,
 			arr[1] = cmd[2];/*sanity */
 			arr[3] = inquiry_evpd_b2(arr[4]);
 		} else {
-			/* Illegal request, invalid field in cdb */
-			mk_sense_buffer(scp, ILLEGAL_REQUEST,
-	INVALID_FIELD_IN_CDB, 0);
+			mk_sense_invalid_fld(scp, SDEB_IN_CDB, 2, -1);
 			kfree(arr);
 			return check_condition_result;
 		}
@@ -1123,8 +1173,7 @@ static int 

Re: [PATCH v2 1/5] scsi_debug: pinpoint invalid field in sense data

2014-11-24 Thread Hannes Reinecke
On 11/25/2014 05:04 AM, Douglas Gilbert wrote:
 Use Sense Key Specific field in the sense data of an ILLEGAL REQUEST
 to optionally pinpoint the location of the problem field. This may
 be either in the cdb or the associated parameter list.
 ---
  drivers/scsi/scsi_debug.c | 138
 +-
  1 file changed, 88 insertions(+), 50 deletions(-)
 
 Signed-off-by: Douglas Gilbert dgilb...@interlog.com

Reviewed-by: Hannes Reinecke h...@suse.de

Cheers,

Hannes
-- 
Dr. Hannes Reinecke   zSeries  Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html