aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2007-09-21 20:38:03 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-12 14:55:40 -0400
commitad355b4628a19ba2af30409e13083edda221a5c9 (patch)
tree775ade42b8a7e67d0c687b54f01f13122c2482db /drivers/ata/libata-scsi.c
parentd4155e6f13e931048036976d9fb47b5db53ee7a3 (diff)
[libata] SCSI: support INQUIRY page 89h (ATA info page)
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c72
1 files changed, 68 insertions, 4 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 7ad046b7c356..b39966299e7b 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,
1804} 1804}
1805 1805
1806/** 1806/**
1807 * ata_scsiop_inq_89 - Simulate INQUIRY VPD page 89, ATA info
1808 * @args: device IDENTIFY data / SCSI command of interest.
1809 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
1810 * @buflen: Response buffer length.
1811 *
1812 * Yields SAT-specified ATA VPD page.
1813 *
1814 * LOCKING:
1815 * spin_lock_irqsave(host lock)
1816 */
1817
1818unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
1819 unsigned int buflen)
1820{
1821 u8 pbuf[60];
1822 struct ata_taskfile tf;
1823 unsigned int i;
1824
1825 if (!buflen)
1826 return 0;
1827
1828 memset(&pbuf, 0, sizeof(pbuf));
1829 memset(&tf, 0, sizeof(tf));
1830
1831 pbuf[1] = 0x89; /* our page code */
1832 pbuf[2] = (0x238 >> 8); /* page size fixed at 238h */
1833 pbuf[3] = (0x238 & 0xff);
1834
1835 memcpy(&pbuf[8], "ATA ", 8);
1836 ata_id_string(args->id, &pbuf[16], ATA_ID_PROD, 16);
1837 ata_id_string(args->id, &pbuf[32], ATA_ID_FW_REV, 4);
1838
1839 /* we don't store the ATA device signature, so we fake it */
1840
1841 tf.command = ATA_DRDY; /* really, this is Status reg */
1842 tf.lbal = 0x1;
1843 tf.nsect = 0x1;
1844
1845 ata_tf_to_fis(&tf, 0, 1, &pbuf[36]); /* TODO: PMP? */
1846 pbuf[36] = 0x34; /* force D2H Reg FIS (34h) */
1847
1848 pbuf[56] = ATA_CMD_ID_ATA;
1849
1850 i = min(buflen, 60U);
1851 memcpy(rbuf, &pbuf[0], i);
1852 buflen -= i;
1853
1854 if (!buflen)
1855 return 0;
1856
1857 memcpy(&rbuf[60], &args->id[0], min(buflen, 512U));
1858 return 0;
1859}
1860
1861/**
1807 * ata_scsiop_noop - Command handler that simply returns success. 1862 * ata_scsiop_noop - Command handler that simply returns success.
1808 * @args: device IDENTIFY data / SCSI command of interest. 1863 * @args: device IDENTIFY data / SCSI command of interest.
1809 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 1864 * @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,
2880 ata_scsi_invalid_field(cmd, done); 2935 ata_scsi_invalid_field(cmd, done);
2881 else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ 2936 else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */
2882 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); 2937 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
2883 else if (scsicmd[2] == 0x00) 2938 else switch (scsicmd[2]) {
2939 case 0x00:
2884 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00); 2940 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00);
2885 else if (scsicmd[2] == 0x80) 2941 break;
2942 case 0x80:
2886 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80); 2943 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80);
2887 else if (scsicmd[2] == 0x83) 2944 break;
2945 case 0x83:
2888 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83); 2946 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83);
2889 else 2947 break;
2948 case 0x89:
2949 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89);
2950 break;
2951 default:
2890 ata_scsi_invalid_field(cmd, done); 2952 ata_scsi_invalid_field(cmd, done);
2953 break;
2954 }
2891 break; 2955 break;
2892 2956
2893 case MODE_SENSE: 2957 case MODE_SENSE: