* [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).