linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] libata: translate INQUIRY VPD page 89h (ATA info)
@ 2007-09-21  9:48 Jeff Garzik
  2007-09-21 14:12 ` James Bottomley
  2007-09-22  0:54 ` [PATCH v2] " Jeff Garzik
  0 siblings, 2 replies; 6+ messages in thread
From: Jeff Garzik @ 2007-09-21  9:48 UTC (permalink / raw)
  To: linux-ide; +Cc: linux-scsi


commit a6d5ac6a3a1cfbed2a045928bbadd5285f1df084
Author: Jeff Garzik <jeff@garzik.org>
Date:   Fri Sep 21 05:07:19 2007 -0400

    [libata] SCSI: support INQUIRY page 89h (ATA info page)
    
    Signed-off-by: Jeff Garzik <jeff@garzik.org>

 drivers/ata/libata-scsi.c |   82 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 78 insertions(+), 4 deletions(-)

a6d5ac6a3a1cfbed2a045928bbadd5285f1df084
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 7ad046b..bb5a5c1 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1804,6 +1804,71 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
 }
 
 /**
+ *	ata_scsiop_inq_89 - Simulate INQUIRY VPD page 89, ATA info
+ *	@args: device IDENTIFY data / SCSI command of interest.
+ *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+ *	@buflen: Response buffer length.
+ *
+ *	Yields SAT-specified ATA VPD page.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host lock)
+ */
+
+unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
+			      unsigned int buflen)
+{
+	struct ata_device *dev = args->dev;
+	u8 pbuf[60];
+	bool is_atapi = (dev->class == ATA_DEV_ATAPI);
+	struct ata_taskfile tf;
+	unsigned int i;
+
+	if (!buflen)
+		return 0;
+
+	memset(&pbuf, 0, sizeof(pbuf));
+	memset(&tf, 0, sizeof(tf));
+
+	if (is_atapi)
+		pbuf[0] = 0x5;	/* FIXME: hardcodes MMC */
+
+	pbuf[1] = 0x89;			/* our page code */
+	pbuf[2] = (0x238 >> 8);		/* page size fixed at 238h */
+	pbuf[3] = (0x238 & 0xff);
+
+	memcpy(&pbuf[8], "ATA     ", 8);
+	ata_id_string(args->id, &pbuf[16], ATA_ID_PROD, 16);
+	ata_id_string(args->id, &pbuf[32], ATA_ID_FW_REV, 4);
+
+	/* we don't store the ATA/ATAPI device signature, so we fake it */
+	if (is_atapi) {
+		tf.command = ATA_CMD_ID_ATAPI;
+		tf.lbam = 0x14;
+		tf.lbah = 0xeb;
+	} else {
+		tf.command = ATA_CMD_ID_ATA;
+	}
+	tf.lbal = 0x1;
+	tf.nsect = 0x1;
+
+	/* FIXME: PMP. don't use H2D Reg FIS. */
+	ata_tf_to_fis(&tf, 0, 1, &pbuf[36]);
+
+	pbuf[56] = tf.command;
+
+	i = min(buflen, 60U);
+	memcpy(rbuf, &pbuf[0], i);
+	buflen -= i;
+
+	if (!i)
+		return 0;
+
+	memcpy(&rbuf[60], &args->id[0], min(buflen, 512U));
+	return 0;
+}
+
+/**
  *	ata_scsiop_noop - Command handler that simply returns success.
  *	@args: device IDENTIFY data / SCSI command of interest.
  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
@@ -2880,14 +2945,23 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
 				ata_scsi_invalid_field(cmd, done);
 			else if ((scsicmd[1] & 1) == 0)    /* is EVPD clear? */
 				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
-			else if (scsicmd[2] == 0x00)
+			else switch (scsicmd[2]) {
+			case 0x00:
 				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00);
-			else if (scsicmd[2] == 0x80)
+				break;
+			case 0x80:
 				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80);
-			else if (scsicmd[2] == 0x83)
+				break;
+			case 0x83:
 				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83);
-			else
+				break;
+			case 0x89:
+				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89);
+				break;
+			default:
 				ata_scsi_invalid_field(cmd, done);
+				break;
+			}
 			break;
 
 		case MODE_SENSE:

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] libata: translate INQUIRY VPD page 89h (ATA info)
  2007-09-21  9:48 [PATCH] libata: translate INQUIRY VPD page 89h (ATA info) Jeff Garzik
@ 2007-09-21 14:12 ` James Bottomley
  2007-09-21 20:05   ` Jeff Garzik
  2007-09-21 23:25   ` Jeff Garzik
  2007-09-22  0:54 ` [PATCH v2] " Jeff Garzik
  1 sibling, 2 replies; 6+ messages in thread
From: James Bottomley @ 2007-09-21 14:12 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide, linux-scsi

On Fri, 2007-09-21 at 05:48 -0400, Jeff Garzik wrote:
> commit a6d5ac6a3a1cfbed2a045928bbadd5285f1df084
> Author: Jeff Garzik <jeff@garzik.org>
> Date:   Fri Sep 21 05:07:19 2007 -0400
> 
>     [libata] SCSI: support INQUIRY page 89h (ATA info page)
>     
>     Signed-off-by: Jeff Garzik <jeff@garzik.org>
> 
>  drivers/ata/libata-scsi.c |   82 +++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 78 insertions(+), 4 deletions(-)
> 
> a6d5ac6a3a1cfbed2a045928bbadd5285f1df084
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index 7ad046b..bb5a5c1 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -1804,6 +1804,71 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
>  }
>  
>  /**
> + *	ata_scsiop_inq_89 - Simulate INQUIRY VPD page 89, ATA info
> + *	@args: device IDENTIFY data / SCSI command of interest.
> + *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
> + *	@buflen: Response buffer length.
> + *
> + *	Yields SAT-specified ATA VPD page.
> + *
> + *	LOCKING:
> + *	spin_lock_irqsave(host lock)
> + */
> +
> +unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
> +			      unsigned int buflen)
> +{
> +	struct ata_device *dev = args->dev;
> +	u8 pbuf[60];
> +	bool is_atapi = (dev->class == ATA_DEV_ATAPI);

I thought this was only used in the dev->class == ATA_DEV_ATA leg of the
ata_scsi_queuecommand(), so isn't this always false?

> +	struct ata_taskfile tf;
> +	unsigned int i;
> +
> +	if (!buflen)
> +		return 0;
> +
> +	memset(&pbuf, 0, sizeof(pbuf));
> +	memset(&tf, 0, sizeof(tf));
> +
> +	if (is_atapi)
> +		pbuf[0] = 0x5;	/* FIXME: hardcodes MMC */

Actually, in MMC implementation of INQUIRY per SPC-3 (or earlier if MMC
< 5) is mandatory.  The problem cases I can see are non-standard ATAPI
devices (probably scanners).

James



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] libata: translate INQUIRY VPD page 89h (ATA info)
  2007-09-21 14:12 ` James Bottomley
@ 2007-09-21 20:05   ` Jeff Garzik
  2007-09-21 23:25   ` Jeff Garzik
  1 sibling, 0 replies; 6+ messages in thread
From: Jeff Garzik @ 2007-09-21 20:05 UTC (permalink / raw)
  To: James Bottomley; +Cc: linux-ide, linux-scsi

James Bottomley wrote:
> On Fri, 2007-09-21 at 05:48 -0400, Jeff Garzik wrote:
>> commit a6d5ac6a3a1cfbed2a045928bbadd5285f1df084
>> Author: Jeff Garzik <jeff@garzik.org>
>> Date:   Fri Sep 21 05:07:19 2007 -0400
>>
>>     [libata] SCSI: support INQUIRY page 89h (ATA info page)
>>     
>>     Signed-off-by: Jeff Garzik <jeff@garzik.org>
>>
>>  drivers/ata/libata-scsi.c |   82 +++++++++++++++++++++++++++++++++++++++++++---
>>  1 file changed, 78 insertions(+), 4 deletions(-)
>>
>> a6d5ac6a3a1cfbed2a045928bbadd5285f1df084
>> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
>> index 7ad046b..bb5a5c1 100644
>> --- a/drivers/ata/libata-scsi.c
>> +++ b/drivers/ata/libata-scsi.c
>> @@ -1804,6 +1804,71 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
>>  }
>>  
>>  /**
>> + *	ata_scsiop_inq_89 - Simulate INQUIRY VPD page 89, ATA info
>> + *	@args: device IDENTIFY data / SCSI command of interest.
>> + *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
>> + *	@buflen: Response buffer length.
>> + *
>> + *	Yields SAT-specified ATA VPD page.
>> + *
>> + *	LOCKING:
>> + *	spin_lock_irqsave(host lock)
>> + */
>> +
>> +unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
>> +			      unsigned int buflen)
>> +{
>> +	struct ata_device *dev = args->dev;
>> +	u8 pbuf[60];
>> +	bool is_atapi = (dev->class == ATA_DEV_ATAPI);
> 
> I thought this was only used in the dev->class == ATA_DEV_ATA leg of the
> ata_scsi_queuecommand(), so isn't this always false?

Actually, yes, you're right.


>> +	struct ata_taskfile tf;
>> +	unsigned int i;
>> +
>> +	if (!buflen)
>> +		return 0;
>> +
>> +	memset(&pbuf, 0, sizeof(pbuf));
>> +	memset(&tf, 0, sizeof(tf));
>> +
>> +	if (is_atapi)
>> +		pbuf[0] = 0x5;	/* FIXME: hardcodes MMC */
> 
> Actually, in MMC implementation of INQUIRY per SPC-3 (or earlier if MMC
> < 5) is mandatory.  The problem cases I can see are non-standard ATAPI
> devices (probably scanners).

The problem at hand is that the device might -not- be an MMC device at all.

But it sounds like that stuff can be removed regardless.

	Jeff




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] libata: translate INQUIRY VPD page 89h (ATA info)
  2007-09-21 14:12 ` James Bottomley
  2007-09-21 20:05   ` Jeff Garzik
@ 2007-09-21 23:25   ` Jeff Garzik
  1 sibling, 0 replies; 6+ messages in thread
From: Jeff Garzik @ 2007-09-21 23:25 UTC (permalink / raw)
  To: James Bottomley; +Cc: linux-ide, linux-scsi

James Bottomley wrote:
> On Fri, 2007-09-21 at 05:48 -0400, Jeff Garzik wrote:
>> commit a6d5ac6a3a1cfbed2a045928bbadd5285f1df084
>> Author: Jeff Garzik <jeff@garzik.org>
>> Date:   Fri Sep 21 05:07:19 2007 -0400
>>
>>     [libata] SCSI: support INQUIRY page 89h (ATA info page)
>>     
>>     Signed-off-by: Jeff Garzik <jeff@garzik.org>
>>
>>  drivers/ata/libata-scsi.c |   82 +++++++++++++++++++++++++++++++++++++++++++---
>>  1 file changed, 78 insertions(+), 4 deletions(-)
>>
>> a6d5ac6a3a1cfbed2a045928bbadd5285f1df084
>> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
>> index 7ad046b..bb5a5c1 100644
>> --- a/drivers/ata/libata-scsi.c
>> +++ b/drivers/ata/libata-scsi.c
>> @@ -1804,6 +1804,71 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
>>  }
>>  
>>  /**
>> + *	ata_scsiop_inq_89 - Simulate INQUIRY VPD page 89, ATA info
>> + *	@args: device IDENTIFY data / SCSI command of interest.
>> + *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
>> + *	@buflen: Response buffer length.
>> + *
>> + *	Yields SAT-specified ATA VPD page.
>> + *
>> + *	LOCKING:
>> + *	spin_lock_irqsave(host lock)
>> + */
>> +
>> +unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
>> +			      unsigned int buflen)
>> +{
>> +	struct ata_device *dev = args->dev;
>> +	u8 pbuf[60];
>> +	bool is_atapi = (dev->class == ATA_DEV_ATAPI);
> 
> I thought this was only used in the dev->class == ATA_DEV_ATA leg of the
> ata_scsi_queuecommand(), so isn't this always false?

Now I remember why this is here -- SAT specifies providing this page 
even for ATAPI devices (optional).  If the SATL chooses to do so, the 
obvious fallout ensues:  snooping and modifying the list of supported 
VPD pages, etc.

That's too cumbersome IMO, so I'm just going to do it for ATA.

So, same end result as with my previous response (atapi checks go away), 
but this was some additional info.


>> +	struct ata_taskfile tf;
>> +	unsigned int i;
>> +
>> +	if (!buflen)
>> +		return 0;
>> +
>> +	memset(&pbuf, 0, sizeof(pbuf));
>> +	memset(&tf, 0, sizeof(tf));
>> +
>> +	if (is_atapi)
>> +		pbuf[0] = 0x5;	/* FIXME: hardcodes MMC */
> 
> Actually, in MMC implementation of INQUIRY per SPC-3 (or earlier if MMC
> < 5) is mandatory.  The problem cases I can see are non-standard ATAPI
> devices (probably scanners).

To be more clear:  pbuf[0] is peripheral device type.  ATAPI devices are 
not limited to device type == 5 (MMC), hence the 'FIXME'.  Tape devices 
are a different device type, for example.

libata treats ATAPI as a pass-through bridge to a conforming SCSI device 
of /any/ type.  There are actually some ATAPI bridges which plug into 
any SCSI-2 device, those these are quite rare in practice.

libata only provides a single modification to any SCSI command passed to 
an ATAPI device:  INQUIRY is fixed up to report scsi-version==5, if 
scsi-version==0 (see atapi_qc_complete).

	Jeff



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2] libata: translate INQUIRY VPD page 89h (ATA info)
  2007-09-21  9:48 [PATCH] libata: translate INQUIRY VPD page 89h (ATA info) Jeff Garzik
  2007-09-21 14:12 ` James Bottomley
@ 2007-09-22  0:54 ` Jeff Garzik
  2007-09-22  1:05   ` Jeff Garzik
  1 sibling, 1 reply; 6+ messages in thread
From: Jeff Garzik @ 2007-09-22  0:54 UTC (permalink / raw)
  To: linux-ide, linux-scsi


Ditched ATAPI, fixed a bug, a few clean-ups and fixmes taken care of.


commit a1c69f03a85fe6fa1b7f2f3726dd7205eb68a328
Author: Jeff Garzik <jeff@garzik.org>
Date:   Fri Sep 21 20:38:03 2007 -0400

    [libata] SCSI: support INQUIRY page 89h (ATA info page)
    
    Signed-off-by: Jeff Garzik <jeff@garzik.org>

 drivers/ata/libata-scsi.c |   72 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 68 insertions(+), 4 deletions(-)

a1c69f03a85fe6fa1b7f2f3726dd7205eb68a328
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 7ad046b..b399662 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1804,6 +1804,61 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
 }
 
 /**
+ *	ata_scsiop_inq_89 - Simulate INQUIRY VPD page 89, ATA info
+ *	@args: device IDENTIFY data / SCSI command of interest.
+ *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+ *	@buflen: Response buffer length.
+ *
+ *	Yields SAT-specified ATA VPD page.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host lock)
+ */
+
+unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
+			      unsigned int buflen)
+{
+	u8 pbuf[60];
+	struct ata_taskfile tf;
+	unsigned int i;
+
+	if (!buflen)
+		return 0;
+
+	memset(&pbuf, 0, sizeof(pbuf));
+	memset(&tf, 0, sizeof(tf));
+
+	pbuf[1] = 0x89;			/* our page code */
+	pbuf[2] = (0x238 >> 8);		/* page size fixed at 238h */
+	pbuf[3] = (0x238 & 0xff);
+
+	memcpy(&pbuf[8], "ATA     ", 8);
+	ata_id_string(args->id, &pbuf[16], ATA_ID_PROD, 16);
+	ata_id_string(args->id, &pbuf[32], ATA_ID_FW_REV, 4);
+
+	/* we don't store the ATA device signature, so we fake it */
+
+	tf.command = ATA_DRDY;		/* really, this is Status reg */
+	tf.lbal = 0x1;
+	tf.nsect = 0x1;
+
+	ata_tf_to_fis(&tf, 0, 1, &pbuf[36]);	/* TODO: PMP? */
+	pbuf[36] = 0x34;		/* force D2H Reg FIS (34h) */
+
+	pbuf[56] = ATA_CMD_ID_ATA;
+
+	i = min(buflen, 60U);
+	memcpy(rbuf, &pbuf[0], i);
+	buflen -= i;
+
+	if (!buflen)
+		return 0;
+
+	memcpy(&rbuf[60], &args->id[0], min(buflen, 512U));
+	return 0;
+}
+
+/**
  *	ata_scsiop_noop - Command handler that simply returns success.
  *	@args: device IDENTIFY data / SCSI command of interest.
  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
@@ -2880,14 +2935,23 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
 				ata_scsi_invalid_field(cmd, done);
 			else if ((scsicmd[1] & 1) == 0)    /* is EVPD clear? */
 				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
-			else if (scsicmd[2] == 0x00)
+			else switch (scsicmd[2]) {
+			case 0x00:
 				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00);
-			else if (scsicmd[2] == 0x80)
+				break;
+			case 0x80:
 				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80);
-			else if (scsicmd[2] == 0x83)
+				break;
+			case 0x83:
 				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83);
-			else
+				break;
+			case 0x89:
+				ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89);
+				break;
+			default:
 				ata_scsi_invalid_field(cmd, done);
+				break;
+			}
 			break;
 
 		case MODE_SENSE:

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] libata: translate INQUIRY VPD page 89h (ATA info)
  2007-09-22  0:54 ` [PATCH v2] " Jeff Garzik
@ 2007-09-22  1:05   ` Jeff Garzik
  0 siblings, 0 replies; 6+ messages in thread
From: Jeff Garzik @ 2007-09-22  1:05 UTC (permalink / raw)
  To: linux-ide, linux-scsi

Jeff Garzik wrote:
> +	memcpy(&pbuf[8], "ATA     ", 8);
> +	ata_id_string(args->id, &pbuf[16], ATA_ID_PROD, 16);
> +	ata_id_string(args->id, &pbuf[32], ATA_ID_FW_REV, 4);


And I just checked in a fix that changes the above to reflect the SCSI 
simulator's vendor/product/version (linux/libata/DRV_VERSION), rather 
than the ATA device's, as the spec wants.

	Jeff



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2007-09-22  1:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-21  9:48 [PATCH] libata: translate INQUIRY VPD page 89h (ATA info) Jeff Garzik
2007-09-21 14:12 ` James Bottomley
2007-09-21 20:05   ` Jeff Garzik
2007-09-21 23:25   ` Jeff Garzik
2007-09-22  0:54 ` [PATCH v2] " Jeff Garzik
2007-09-22  1:05   ` Jeff Garzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).