diff options
author | Jeff Garzik <jeff@garzik.org> | 2007-09-21 20:38:03 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-12 14:55:40 -0400 |
commit | ad355b4628a19ba2af30409e13083edda221a5c9 (patch) | |
tree | 775ade42b8a7e67d0c687b54f01f13122c2482db /drivers/ata/libata-scsi.c | |
parent | d4155e6f13e931048036976d9fb47b5db53ee7a3 (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.c | 72 |
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 | |||
1818 | unsigned 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: |