commit a6d5ac6a3a1cfbed2a045928bbadd5285f1df084
Author: Jeff Garzik <[EMAIL PROTECTED]>
Date: Fri Sep 21 05:07:19 2007 -0400
[libata] SCSI: support INQUIRY page 89h (ATA info page)
Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
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:
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html