All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hannes Reinecke <hare@suse.de>
To: Tejun Heo <tj@kernel.org>
Cc: linux-ide@vger.kernel.org,
	"Martin K. Petersen" <martin.petersen@oracle.com>,
	Christoph Hellwig <hch@lst.de>,
	Shaun Tancheff <shaun.tancheff@seagate.com>,
	Damien Le Moal <damien.lemoal@hgst.com>,
	linux-scsi@vger.kernel.org,
	Sathya Prakash <sathya.prakash@broadcom.com>,
	Hannes Reinecke <hare@suse.de>, Hannes Reinecke <hare@suse.com>
Subject: [PATCH 14/14] libata-scsi: Set information sense field for invalid parameter
Date: Mon,  4 Apr 2016 11:44:07 +0200	[thread overview]
Message-ID: <1459763047-125551-15-git-send-email-hare@suse.de> (raw)
In-Reply-To: <1459763047-125551-1-git-send-email-hare@suse.de>

Whenever the sense key is set to 'invalid parameter' we should
be filling out the sense-key specific information field in the
sense buffer.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/ata/libata-scsi.c | 79 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 59 insertions(+), 20 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index d72d78d..d29832f 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -309,6 +309,15 @@ static void ata_scsi_set_invalid_field(struct ata_device *dev,
 				     field, bit, 1);
 }
 
+static void ata_scsi_set_invalid_parameter(struct ata_device *dev,
+					   struct scsi_cmnd *cmd, u16 field)
+{
+	/* "Invalid field in parameter list" */
+	ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x26, 0x0);
+	scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE,
+				     field, 0xff, 0);
+}
+
 static ssize_t
 ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count)
@@ -3313,20 +3322,26 @@ invalid_opcode:
  *	None.
  */
 static int ata_mselect_caching(struct ata_queued_cmd *qc,
-			       const u8 *buf, int len)
+			       const u8 *buf, int len, u16 *fp)
 {
 	struct ata_taskfile *tf = &qc->tf;
 	struct ata_device *dev = qc->dev;
 	char mpage[CACHE_MPAGE_LEN];
 	u8 wce;
+	int i;
 
 	/*
 	 * The first two bytes of def_cache_mpage are a header, so offsets
 	 * in mpage are off by 2 compared to buf.  Same for len.
 	 */
 
-	if (len != CACHE_MPAGE_LEN - 2)
+	if (len != CACHE_MPAGE_LEN - 2) {
+		if (len < CACHE_MPAGE_LEN - 2)
+			*fp = len;
+		else
+			*fp = CACHE_MPAGE_LEN - 2;
 		return -EINVAL;
+	}
 
 	wce = buf[0] & (1 << 2);
 
@@ -3334,10 +3349,14 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
 	 * Check that read-only bits are not modified.
 	 */
 	ata_msense_caching(dev->id, mpage, false);
-	mpage[2] &= ~(1 << 2);
-	mpage[2] |= wce;
-	if (memcmp(mpage + 2, buf, CACHE_MPAGE_LEN - 2) != 0)
-		return -EINVAL;
+	for (i = 0; i < CACHE_MPAGE_LEN - 2; i++) {
+		if (i == 0)
+			continue;
+		if (mpage[i + 2] != buf[i]) {
+			*fp = i;
+			return -EINVAL;
+		}
+	}
 
 	tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
 	tf->protocol = ATA_PROT_NODATA;
@@ -3359,19 +3378,25 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
  *	None.
  */
 static int ata_mselect_control(struct ata_queued_cmd *qc,
-			       const u8 *buf, int len)
+			       const u8 *buf, int len, u16 *fp)
 {
 	struct ata_device *dev = qc->dev;
 	char mpage[CONTROL_MPAGE_LEN];
 	u8 d_sense;
+	int i;
 
 	/*
 	 * The first two bytes of def_control_mpage are a header, so offsets
 	 * in mpage are off by 2 compared to buf.  Same for len.
 	 */
 
-	if (len != CONTROL_MPAGE_LEN - 2)
+	if (len != CONTROL_MPAGE_LEN - 2) {
+		if (len < CONTROL_MPAGE_LEN - 2)
+			*fp = len;
+		else
+			*fp = CONTROL_MPAGE_LEN - 2;
 		return -EINVAL;
+	}
 
 	d_sense = buf[0] & (1 << 2);
 
@@ -3379,10 +3404,14 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
 	 * Check that read-only bits are not modified.
 	 */
 	ata_msense_ctl_mode(dev, mpage, false);
-	mpage[2] &= ~(1 << 2);
-	mpage[2] |= d_sense;
-	if (memcmp(mpage + 2, buf, CONTROL_MPAGE_LEN - 2) != 0)
-		return -EINVAL;
+	for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) {
+		if (i == 0)
+			continue;
+		if (mpage[2 + i] != buf[i]) {
+			*fp = i;
+			return -EINVAL;
+		}
+	}
 	if (d_sense & (1 << 2))
 		dev->flags |= ATA_DFLAG_D_SENSE;
 	else
@@ -3411,8 +3440,8 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
 	u8 pg, spg;
 	unsigned six_byte, pg_len, hdr_len, bd_len;
 	int len;
-	u16 fp;
-	u8 bp;
+	u16 fp = (u16)-1;
+	u8 bp = 0xff;
 
 	VPRINTK("ENTER\n");
 
@@ -3461,8 +3490,11 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
 	p += hdr_len;
 	if (len < bd_len)
 		goto invalid_param_len;
-	if (bd_len != 0 && bd_len != 8)
+	if (bd_len != 0 && bd_len != 8) {
+		fp = (six_byte) ? 3 : 6;
+		fp += bd_len + hdr_len;
 		goto invalid_param;
+	}
 
 	len -= bd_len;
 	p += bd_len;
@@ -3493,21 +3525,29 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
 	 * No mode subpages supported (yet) but asking for _all_
 	 * subpages may be valid
 	 */
-	if (spg && (spg != ALL_SUB_MPAGES))
+	if (spg && (spg != ALL_SUB_MPAGES)) {
+		fp = (p[0] & 0x40) ? 1 : 0;
+		fp += hdr_len + bd_len;
 		goto invalid_param;
+	}
 	if (pg_len > len)
 		goto invalid_param_len;
 
 	switch (pg) {
 	case CACHE_MPAGE:
-		if (ata_mselect_caching(qc, p, pg_len) < 0)
+		if (ata_mselect_caching(qc, p, pg_len, &fp) < 0) {
+			fp += hdr_len + bd_len;
 			goto invalid_param;
+		}
 		break;
 	case CONTROL_MPAGE:
-		if (ata_mselect_control(qc, p, pg_len) < 0)
+		if (ata_mselect_control(qc, p, pg_len, &fp) < 0) {
+			fp += hdr_len + bd_len;
 			goto invalid_param;
+		}
 		break;
 	default:		/* invalid page code */
+		fp = bd_len + hdr_len;
 		goto invalid_param;
 	}
 
@@ -3525,8 +3565,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
 	return 1;
 
  invalid_param:
-	/* "Invalid field in parameter list" */
-	ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x26, 0x0);
+	ata_scsi_set_invalid_parameter(qc->dev, scmd, fp);
 	return 1;
 
  invalid_param_len:
-- 
1.8.5.6


  parent reply	other threads:[~2016-04-04  9:44 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-04  9:43 [PATCH 00/14] libata: SATL update Hannes Reinecke
2016-04-04  9:43 ` [PATCH 01/14] libata: Implement NCQ autosense Hannes Reinecke
2016-04-04  9:43 ` [PATCH 02/14] libata: Implement support for sense data reporting Hannes Reinecke
2016-04-04  9:43 ` [PATCH 03/14] libata-scsi: sanitize ata_gen_ata_sense() Hannes Reinecke
2016-04-04 11:26   ` Sergei Shtylyov
2016-04-04 16:22     ` Tejun Heo
2016-04-04 17:33       ` Sergei Shtylyov
2016-04-04  9:43 ` [PATCH 04/14] libata: sanitize ata_tf_read_block() Hannes Reinecke
2016-04-04  9:43 ` [PATCH 05/14] libata-scsi: use scsi_set_sense_information() Hannes Reinecke
2016-04-04  9:43 ` [PATCH 06/14] libata-eh: Set 'information' field for autosense Hannes Reinecke
2016-04-04  9:44 ` [PATCH 07/14] libata-scsi: use ata_scsi_set_sense() Hannes Reinecke
2016-04-04  9:44 ` [PATCH 08/14] libata: evaluate SCSI sense code Hannes Reinecke
2016-04-04 11:21   ` Sergei Shtylyov
2016-04-04  9:44 ` [PATCH 09/14] libata-scsi: generate correct ATA pass-through sense Hannes Reinecke
2016-04-04  9:44 ` [PATCH 10/14] libata: Implement control mode page to select sense format Hannes Reinecke
2016-04-04 12:53   ` kbuild test robot
2016-04-04  9:44 ` [PATCH 11/14] scsi: add scsi_set_sense_field_pointer() Hannes Reinecke
2016-04-04  9:44 ` [PATCH 12/14] libata-scsi: Set field pointer in sense code Hannes Reinecke
2016-04-04  9:44 ` [PATCH 13/14] libata-scsi: set bit pointer for sense code information Hannes Reinecke
2016-04-04  9:44 ` Hannes Reinecke [this message]
2016-04-04 15:22   ` [PATCH 14/14] libata-scsi: Set information sense field for invalid parameter kbuild test robot
2016-04-04 15:46 ` [PATCH 00/14] libata: SATL update Tejun Heo
2016-04-04 19:54   ` Hannes Reinecke

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1459763047-125551-15-git-send-email-hare@suse.de \
    --to=hare@suse.de \
    --cc=damien.lemoal@hgst.com \
    --cc=hare@suse.com \
    --cc=hch@lst.de \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=sathya.prakash@broadcom.com \
    --cc=shaun.tancheff@seagate.com \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.