aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-04-28 04:48:51 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-29 02:17:03 -0400
commit87340e98345155631f7a1a4d8d66cf0ab286cb1b (patch)
tree311ce808242cc06c65f976b4ce3c0c46c1110197 /drivers/ata/libata-scsi.c
parentf0761be344f9b1cc4284b1d945933cd983c233a4 (diff)
libata-scsi: improve rbuf handling for simulated commands
Buffer length handling in simulated commands is error-prone and full of bugs. There are a number of places where necessary length checks are missing and if the output buffer is passed in as sglist, nothing works. This patch adds a static buffer ata_scsi_rbuf which is sufficiently large to handle the larges output from simulated commands (4k currently), let all simulte functions write to the buffer and removes all length checks as we know that there always is enough buffer space. Copying in (for ATAPI inquiry fix up) and out are handled by sg_copy_to/from_buffer() behind ata_scsi_rbuf_get/put() interface which handles sglist properly. This patch is inspired from buffer length check fix patch from Petr Vandrovec. Updated to use sg_copy_to/from_buffer() as suggested by FUJITA Tomonori. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Petr Vandrovec <petr@vmware.com> Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c444
1 files changed, 154 insertions, 290 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index e516816f66a6..3ce43920e459 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -49,7 +49,11 @@
49 49
50#include "libata.h" 50#include "libata.h"
51 51
52#define SECTOR_SIZE 512 52#define SECTOR_SIZE 512
53#define ATA_SCSI_RBUF_SIZE 4096
54
55static DEFINE_SPINLOCK(ata_scsi_rbuf_lock);
56static u8 ata_scsi_rbuf[ATA_SCSI_RBUF_SIZE];
53 57
54typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); 58typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc);
55 59
@@ -1639,53 +1643,48 @@ defer:
1639 1643
1640/** 1644/**
1641 * ata_scsi_rbuf_get - Map response buffer. 1645 * ata_scsi_rbuf_get - Map response buffer.
1642 * @cmd: SCSI command containing buffer to be mapped. 1646 * @flags: unsigned long variable to store irq enable status
1643 * @buf_out: Pointer to mapped area. 1647 * @copy_in: copy in from user buffer
1644 * 1648 *
1645 * Maps buffer contained within SCSI command @cmd. 1649 * Prepare buffer for simulated SCSI commands.
1646 * 1650 *
1647 * LOCKING: 1651 * LOCKING:
1648 * spin_lock_irqsave(host lock) 1652 * spin_lock_irqsave(ata_scsi_rbuf_lock) on success
1649 * 1653 *
1650 * RETURNS: 1654 * RETURNS:
1651 * Length of response buffer. 1655 * Pointer to response buffer.
1652 */ 1656 */
1653 1657static void *ata_scsi_rbuf_get(struct scsi_cmnd *cmd, bool copy_in,
1654static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out) 1658 unsigned long *flags)
1655{ 1659{
1656 u8 *buf; 1660 spin_lock_irqsave(&ata_scsi_rbuf_lock, *flags);
1657 unsigned int buflen;
1658
1659 struct scatterlist *sg = scsi_sglist(cmd);
1660
1661 if (sg) {
1662 buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
1663 buflen = sg->length;
1664 } else {
1665 buf = NULL;
1666 buflen = 0;
1667 }
1668 1661
1669 *buf_out = buf; 1662 memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE);
1670 return buflen; 1663 if (copy_in)
1664 sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
1665 ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE);
1666 return ata_scsi_rbuf;
1671} 1667}
1672 1668
1673/** 1669/**
1674 * ata_scsi_rbuf_put - Unmap response buffer. 1670 * ata_scsi_rbuf_put - Unmap response buffer.
1675 * @cmd: SCSI command containing buffer to be unmapped. 1671 * @cmd: SCSI command containing buffer to be unmapped.
1676 * @buf: buffer to unmap 1672 * @copy_out: copy out result
1673 * @flags: @flags passed to ata_scsi_rbuf_get()
1677 * 1674 *
1678 * Unmaps response buffer contained within @cmd. 1675 * Returns rbuf buffer. The result is copied to @cmd's buffer if
1676 * @copy_back is true.
1679 * 1677 *
1680 * LOCKING: 1678 * LOCKING:
1681 * spin_lock_irqsave(host lock) 1679 * Unlocks ata_scsi_rbuf_lock.
1682 */ 1680 */
1683 1681static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, bool copy_out,
1684static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf) 1682 unsigned long *flags)
1685{ 1683{
1686 struct scatterlist *sg = scsi_sglist(cmd); 1684 if (copy_out)
1687 if (sg) 1685 sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
1688 kunmap_atomic(buf - sg->offset, KM_IRQ0); 1686 ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE);
1687 spin_unlock_irqrestore(&ata_scsi_rbuf_lock, *flags);
1689} 1688}
1690 1689
1691/** 1690/**
@@ -1704,22 +1703,16 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
1704 * spin_lock_irqsave(host lock) 1703 * spin_lock_irqsave(host lock)
1705 */ 1704 */
1706static void ata_scsi_rbuf_fill(struct ata_scsi_args *args, 1705static void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
1707 unsigned int (*actor)(struct ata_scsi_args *args, 1706 unsigned int (*actor)(struct ata_scsi_args *args, u8 *rbuf))
1708 u8 *rbuf, unsigned int buflen))
1709{ 1707{
1710 u8 *rbuf; 1708 u8 *rbuf;
1711 unsigned int buflen, rc; 1709 unsigned int rc;
1712 struct scsi_cmnd *cmd = args->cmd; 1710 struct scsi_cmnd *cmd = args->cmd;
1713 unsigned long flags; 1711 unsigned long flags;
1714 1712
1715 local_irq_save(flags); 1713 rbuf = ata_scsi_rbuf_get(cmd, false, &flags);
1716 1714 rc = actor(args, rbuf);
1717 buflen = ata_scsi_rbuf_get(cmd, &rbuf); 1715 ata_scsi_rbuf_put(cmd, rc == 0, &flags);
1718 memset(rbuf, 0, buflen);
1719 rc = actor(args, rbuf, buflen);
1720 ata_scsi_rbuf_put(cmd, rbuf);
1721
1722 local_irq_restore(flags);
1723 1716
1724 if (rc == 0) 1717 if (rc == 0)
1725 cmd->result = SAM_STAT_GOOD; 1718 cmd->result = SAM_STAT_GOOD;
@@ -1727,26 +1720,9 @@ static void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
1727} 1720}
1728 1721
1729/** 1722/**
1730 * ATA_SCSI_RBUF_SET - helper to set values in SCSI response buffer
1731 * @idx: byte index into SCSI response buffer
1732 * @val: value to set
1733 *
1734 * To be used by SCSI command simulator functions. This macros
1735 * expects two local variables, u8 *rbuf and unsigned int buflen,
1736 * are in scope.
1737 *
1738 * LOCKING:
1739 * None.
1740 */
1741#define ATA_SCSI_RBUF_SET(idx, val) do { \
1742 if ((idx) < buflen) rbuf[(idx)] = (u8)(val); \
1743 } while (0)
1744
1745/**
1746 * ata_scsiop_inq_std - Simulate INQUIRY command 1723 * ata_scsiop_inq_std - Simulate INQUIRY command
1747 * @args: device IDENTIFY data / SCSI command of interest. 1724 * @args: device IDENTIFY data / SCSI command of interest.
1748 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 1725 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
1749 * @buflen: Response buffer length.
1750 * 1726 *
1751 * Returns standard device identification data associated 1727 * Returns standard device identification data associated
1752 * with non-VPD INQUIRY command output. 1728 * with non-VPD INQUIRY command output.
@@ -1754,9 +1730,17 @@ static void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
1754 * LOCKING: 1730 * LOCKING:
1755 * spin_lock_irqsave(host lock) 1731 * spin_lock_irqsave(host lock)
1756 */ 1732 */
1757static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, 1733static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
1758 unsigned int buflen)
1759{ 1734{
1735 const u8 versions[] = {
1736 0x60, /* SAM-3 (no version claimed) */
1737
1738 0x03,
1739 0x20, /* SBC-2 (no version claimed) */
1740
1741 0x02,
1742 0x60 /* SPC-3 (no version claimed) */
1743 };
1760 u8 hdr[] = { 1744 u8 hdr[] = {
1761 TYPE_DISK, 1745 TYPE_DISK,
1762 0, 1746 0,
@@ -1765,35 +1749,21 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
1765 95 - 4 1749 95 - 4
1766 }; 1750 };
1767 1751
1752 VPRINTK("ENTER\n");
1753
1768 /* set scsi removeable (RMB) bit per ata bit */ 1754 /* set scsi removeable (RMB) bit per ata bit */
1769 if (ata_id_removeable(args->id)) 1755 if (ata_id_removeable(args->id))
1770 hdr[1] |= (1 << 7); 1756 hdr[1] |= (1 << 7);
1771 1757
1772 VPRINTK("ENTER\n");
1773
1774 memcpy(rbuf, hdr, sizeof(hdr)); 1758 memcpy(rbuf, hdr, sizeof(hdr));
1759 memcpy(&rbuf[8], "ATA ", 8);
1760 ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16);
1761 ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4);
1775 1762
1776 if (buflen > 35) { 1763 if (rbuf[32] == 0 || rbuf[32] == ' ')
1777 memcpy(&rbuf[8], "ATA ", 8); 1764 memcpy(&rbuf[32], "n/a ", 4);
1778 ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16);
1779 ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4);
1780 if (rbuf[32] == 0 || rbuf[32] == ' ')
1781 memcpy(&rbuf[32], "n/a ", 4);
1782 }
1783
1784 if (buflen > 63) {
1785 const u8 versions[] = {
1786 0x60, /* SAM-3 (no version claimed) */
1787
1788 0x03,
1789 0x20, /* SBC-2 (no version claimed) */
1790 1765
1791 0x02, 1766 memcpy(rbuf + 59, versions, sizeof(versions));
1792 0x60 /* SPC-3 (no version claimed) */
1793 };
1794
1795 memcpy(rbuf + 59, versions, sizeof(versions));
1796 }
1797 1767
1798 return 0; 1768 return 0;
1799} 1769}
@@ -1802,26 +1772,22 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
1802 * ata_scsiop_inq_00 - Simulate INQUIRY VPD page 0, list of pages 1772 * ata_scsiop_inq_00 - Simulate INQUIRY VPD page 0, list of pages
1803 * @args: device IDENTIFY data / SCSI command of interest. 1773 * @args: device IDENTIFY data / SCSI command of interest.
1804 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 1774 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
1805 * @buflen: Response buffer length.
1806 * 1775 *
1807 * Returns list of inquiry VPD pages available. 1776 * Returns list of inquiry VPD pages available.
1808 * 1777 *
1809 * LOCKING: 1778 * LOCKING:
1810 * spin_lock_irqsave(host lock) 1779 * spin_lock_irqsave(host lock)
1811 */ 1780 */
1812static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf, 1781static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
1813 unsigned int buflen)
1814{ 1782{
1815 const u8 pages[] = { 1783 const u8 pages[] = {
1816 0x00, /* page 0x00, this page */ 1784 0x00, /* page 0x00, this page */
1817 0x80, /* page 0x80, unit serial no page */ 1785 0x80, /* page 0x80, unit serial no page */
1818 0x83 /* page 0x83, device ident page */ 1786 0x83 /* page 0x83, device ident page */
1819 }; 1787 };
1820 rbuf[3] = sizeof(pages); /* number of supported VPD pages */
1821
1822 if (buflen > 6)
1823 memcpy(rbuf + 4, pages, sizeof(pages));
1824 1788
1789 rbuf[3] = sizeof(pages); /* number of supported VPD pages */
1790 memcpy(rbuf + 4, pages, sizeof(pages));
1825 return 0; 1791 return 0;
1826} 1792}
1827 1793
@@ -1829,15 +1795,13 @@ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf,
1829 * ata_scsiop_inq_80 - Simulate INQUIRY VPD page 80, device serial number 1795 * ata_scsiop_inq_80 - Simulate INQUIRY VPD page 80, device serial number
1830 * @args: device IDENTIFY data / SCSI command of interest. 1796 * @args: device IDENTIFY data / SCSI command of interest.
1831 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 1797 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
1832 * @buflen: Response buffer length.
1833 * 1798 *
1834 * Returns ATA device serial number. 1799 * Returns ATA device serial number.
1835 * 1800 *
1836 * LOCKING: 1801 * LOCKING:
1837 * spin_lock_irqsave(host lock) 1802 * spin_lock_irqsave(host lock)
1838 */ 1803 */
1839static unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf, 1804static unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf)
1840 unsigned int buflen)
1841{ 1805{
1842 const u8 hdr[] = { 1806 const u8 hdr[] = {
1843 0, 1807 0,
@@ -1845,12 +1809,10 @@ static unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf,
1845 0, 1809 0,
1846 ATA_ID_SERNO_LEN, /* page len */ 1810 ATA_ID_SERNO_LEN, /* page len */
1847 }; 1811 };
1848 memcpy(rbuf, hdr, sizeof(hdr));
1849
1850 if (buflen > (ATA_ID_SERNO_LEN + 4 - 1))
1851 ata_id_string(args->id, (unsigned char *) &rbuf[4],
1852 ATA_ID_SERNO, ATA_ID_SERNO_LEN);
1853 1812
1813 memcpy(rbuf, hdr, sizeof(hdr));
1814 ata_id_string(args->id, (unsigned char *) &rbuf[4],
1815 ATA_ID_SERNO, ATA_ID_SERNO_LEN);
1854 return 0; 1816 return 0;
1855} 1817}
1856 1818
@@ -1858,7 +1820,6 @@ static unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf,
1858 * ata_scsiop_inq_83 - Simulate INQUIRY VPD page 83, device identity 1820 * ata_scsiop_inq_83 - Simulate INQUIRY VPD page 83, device identity
1859 * @args: device IDENTIFY data / SCSI command of interest. 1821 * @args: device IDENTIFY data / SCSI command of interest.
1860 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 1822 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
1861 * @buflen: Response buffer length.
1862 * 1823 *
1863 * Yields two logical unit device identification designators: 1824 * Yields two logical unit device identification designators:
1864 * - vendor specific ASCII containing the ATA serial number 1825 * - vendor specific ASCII containing the ATA serial number
@@ -1868,40 +1829,37 @@ static unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf,
1868 * LOCKING: 1829 * LOCKING:
1869 * spin_lock_irqsave(host lock) 1830 * spin_lock_irqsave(host lock)
1870 */ 1831 */
1871static unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, 1832static unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf)
1872 unsigned int buflen)
1873{ 1833{
1874 int num;
1875 const int sat_model_serial_desc_len = 68; 1834 const int sat_model_serial_desc_len = 68;
1835 int num;
1876 1836
1877 rbuf[1] = 0x83; /* this page code */ 1837 rbuf[1] = 0x83; /* this page code */
1878 num = 4; 1838 num = 4;
1879 1839
1880 if (buflen > (ATA_ID_SERNO_LEN + num + 3)) { 1840 /* piv=0, assoc=lu, code_set=ACSII, designator=vendor */
1881 /* piv=0, assoc=lu, code_set=ACSII, designator=vendor */ 1841 rbuf[num + 0] = 2;
1882 rbuf[num + 0] = 2; 1842 rbuf[num + 3] = ATA_ID_SERNO_LEN;
1883 rbuf[num + 3] = ATA_ID_SERNO_LEN; 1843 num += 4;
1884 num += 4; 1844 ata_id_string(args->id, (unsigned char *) rbuf + num,
1885 ata_id_string(args->id, (unsigned char *) rbuf + num, 1845 ATA_ID_SERNO, ATA_ID_SERNO_LEN);
1886 ATA_ID_SERNO, ATA_ID_SERNO_LEN); 1846 num += ATA_ID_SERNO_LEN;
1887 num += ATA_ID_SERNO_LEN; 1847
1888 } 1848 /* SAT defined lu model and serial numbers descriptor */
1889 if (buflen > (sat_model_serial_desc_len + num + 3)) { 1849 /* piv=0, assoc=lu, code_set=ACSII, designator=t10 vendor id */
1890 /* SAT defined lu model and serial numbers descriptor */ 1850 rbuf[num + 0] = 2;
1891 /* piv=0, assoc=lu, code_set=ACSII, designator=t10 vendor id */ 1851 rbuf[num + 1] = 1;
1892 rbuf[num + 0] = 2; 1852 rbuf[num + 3] = sat_model_serial_desc_len;
1893 rbuf[num + 1] = 1; 1853 num += 4;
1894 rbuf[num + 3] = sat_model_serial_desc_len; 1854 memcpy(rbuf + num, "ATA ", 8);
1895 num += 4; 1855 num += 8;
1896 memcpy(rbuf + num, "ATA ", 8); 1856 ata_id_string(args->id, (unsigned char *) rbuf + num, ATA_ID_PROD,
1897 num += 8; 1857 ATA_ID_PROD_LEN);
1898 ata_id_string(args->id, (unsigned char *) rbuf + num, 1858 num += ATA_ID_PROD_LEN;
1899 ATA_ID_PROD, ATA_ID_PROD_LEN); 1859 ata_id_string(args->id, (unsigned char *) rbuf + num, ATA_ID_SERNO,
1900 num += ATA_ID_PROD_LEN; 1860 ATA_ID_SERNO_LEN);
1901 ata_id_string(args->id, (unsigned char *) rbuf + num, 1861 num += ATA_ID_SERNO_LEN;
1902 ATA_ID_SERNO, ATA_ID_SERNO_LEN); 1862
1903 num += ATA_ID_SERNO_LEN;
1904 }
1905 rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */ 1863 rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */
1906 return 0; 1864 return 0;
1907} 1865}
@@ -1910,34 +1868,26 @@ static unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
1910 * ata_scsiop_inq_89 - Simulate INQUIRY VPD page 89, ATA info 1868 * ata_scsiop_inq_89 - Simulate INQUIRY VPD page 89, ATA info
1911 * @args: device IDENTIFY data / SCSI command of interest. 1869 * @args: device IDENTIFY data / SCSI command of interest.
1912 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 1870 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
1913 * @buflen: Response buffer length.
1914 * 1871 *
1915 * Yields SAT-specified ATA VPD page. 1872 * Yields SAT-specified ATA VPD page.
1916 * 1873 *
1917 * LOCKING: 1874 * LOCKING:
1918 * spin_lock_irqsave(host lock) 1875 * spin_lock_irqsave(host lock)
1919 */ 1876 */
1920static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf, 1877static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf)
1921 unsigned int buflen)
1922{ 1878{
1923 u8 pbuf[60];
1924 struct ata_taskfile tf; 1879 struct ata_taskfile tf;
1925 unsigned int i;
1926 1880
1927 if (!buflen)
1928 return 0;
1929
1930 memset(&pbuf, 0, sizeof(pbuf));
1931 memset(&tf, 0, sizeof(tf)); 1881 memset(&tf, 0, sizeof(tf));
1932 1882
1933 pbuf[1] = 0x89; /* our page code */ 1883 rbuf[1] = 0x89; /* our page code */
1934 pbuf[2] = (0x238 >> 8); /* page size fixed at 238h */ 1884 rbuf[2] = (0x238 >> 8); /* page size fixed at 238h */
1935 pbuf[3] = (0x238 & 0xff); 1885 rbuf[3] = (0x238 & 0xff);
1936 1886
1937 memcpy(&pbuf[8], "linux ", 8); 1887 memcpy(&rbuf[8], "linux ", 8);
1938 memcpy(&pbuf[16], "libata ", 16); 1888 memcpy(&rbuf[16], "libata ", 16);
1939 memcpy(&pbuf[32], DRV_VERSION, 4); 1889 memcpy(&rbuf[32], DRV_VERSION, 4);
1940 ata_id_string(args->id, &pbuf[32], ATA_ID_FW_REV, 4); 1890 ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4);
1941 1891
1942 /* we don't store the ATA device signature, so we fake it */ 1892 /* we don't store the ATA device signature, so we fake it */
1943 1893
@@ -1945,19 +1895,12 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
1945 tf.lbal = 0x1; 1895 tf.lbal = 0x1;
1946 tf.nsect = 0x1; 1896 tf.nsect = 0x1;
1947 1897
1948 ata_tf_to_fis(&tf, 0, 1, &pbuf[36]); /* TODO: PMP? */ 1898 ata_tf_to_fis(&tf, 0, 1, &rbuf[36]); /* TODO: PMP? */
1949 pbuf[36] = 0x34; /* force D2H Reg FIS (34h) */ 1899 rbuf[36] = 0x34; /* force D2H Reg FIS (34h) */
1950
1951 pbuf[56] = ATA_CMD_ID_ATA;
1952 1900
1953 i = min(buflen, 60U); 1901 rbuf[56] = ATA_CMD_ID_ATA;
1954 memcpy(rbuf, &pbuf[0], i);
1955 buflen -= i;
1956
1957 if (!buflen)
1958 return 0;
1959 1902
1960 memcpy(&rbuf[60], &args->id[0], min(buflen, 512U)); 1903 memcpy(&rbuf[60], &args->id[0], 512);
1961 return 0; 1904 return 0;
1962} 1905}
1963 1906
@@ -1965,7 +1908,6 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
1965 * ata_scsiop_noop - Command handler that simply returns success. 1908 * ata_scsiop_noop - Command handler that simply returns success.
1966 * @args: device IDENTIFY data / SCSI command of interest. 1909 * @args: device IDENTIFY data / SCSI command of interest.
1967 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 1910 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
1968 * @buflen: Response buffer length.
1969 * 1911 *
1970 * No operation. Simply returns success to caller, to indicate 1912 * No operation. Simply returns success to caller, to indicate
1971 * that the caller should successfully complete this SCSI command. 1913 * that the caller should successfully complete this SCSI command.
@@ -1973,46 +1915,16 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
1973 * LOCKING: 1915 * LOCKING:
1974 * spin_lock_irqsave(host lock) 1916 * spin_lock_irqsave(host lock)
1975 */ 1917 */
1976static unsigned int ata_scsiop_noop(struct ata_scsi_args *args, u8 *rbuf, 1918static unsigned int ata_scsiop_noop(struct ata_scsi_args *args, u8 *rbuf)
1977 unsigned int buflen)
1978{ 1919{
1979 VPRINTK("ENTER\n"); 1920 VPRINTK("ENTER\n");
1980 return 0; 1921 return 0;
1981} 1922}
1982 1923
1983/** 1924/**
1984 * ata_msense_push - Push data onto MODE SENSE data output buffer
1985 * @ptr_io: (input/output) Location to store more output data
1986 * @last: End of output data buffer
1987 * @buf: Pointer to BLOB being added to output buffer
1988 * @buflen: Length of BLOB
1989 *
1990 * Store MODE SENSE data on an output buffer.
1991 *
1992 * LOCKING:
1993 * None.
1994 */
1995
1996static void ata_msense_push(u8 **ptr_io, const u8 *last,
1997 const u8 *buf, unsigned int buflen)
1998{
1999 u8 *ptr = *ptr_io;
2000
2001 if ((ptr + buflen - 1) > last)
2002 return;
2003
2004 memcpy(ptr, buf, buflen);
2005
2006 ptr += buflen;
2007
2008 *ptr_io = ptr;
2009}
2010
2011/**
2012 * ata_msense_caching - Simulate MODE SENSE caching info page 1925 * ata_msense_caching - Simulate MODE SENSE caching info page
2013 * @id: device IDENTIFY data 1926 * @id: device IDENTIFY data
2014 * @ptr_io: (input/output) Location to store more output data 1927 * @buf: output buffer
2015 * @last: End of output data buffer
2016 * 1928 *
2017 * Generate a caching info page, which conditionally indicates 1929 * Generate a caching info page, which conditionally indicates
2018 * write caching to the SCSI layer, depending on device 1930 * write caching to the SCSI layer, depending on device
@@ -2021,58 +1933,43 @@ static void ata_msense_push(u8 **ptr_io, const u8 *last,
2021 * LOCKING: 1933 * LOCKING:
2022 * None. 1934 * None.
2023 */ 1935 */
2024 1936static unsigned int ata_msense_caching(u16 *id, u8 *buf)
2025static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io,
2026 const u8 *last)
2027{ 1937{
2028 u8 page[CACHE_MPAGE_LEN]; 1938 memcpy(buf, def_cache_mpage, sizeof(def_cache_mpage));
2029
2030 memcpy(page, def_cache_mpage, sizeof(page));
2031 if (ata_id_wcache_enabled(id)) 1939 if (ata_id_wcache_enabled(id))
2032 page[2] |= (1 << 2); /* write cache enable */ 1940 buf[2] |= (1 << 2); /* write cache enable */
2033 if (!ata_id_rahead_enabled(id)) 1941 if (!ata_id_rahead_enabled(id))
2034 page[12] |= (1 << 5); /* disable read ahead */ 1942 buf[12] |= (1 << 5); /* disable read ahead */
2035 1943 return sizeof(def_cache_mpage);
2036 ata_msense_push(ptr_io, last, page, sizeof(page));
2037 return sizeof(page);
2038} 1944}
2039 1945
2040/** 1946/**
2041 * ata_msense_ctl_mode - Simulate MODE SENSE control mode page 1947 * ata_msense_ctl_mode - Simulate MODE SENSE control mode page
2042 * @dev: Device associated with this MODE SENSE command 1948 * @buf: output buffer
2043 * @ptr_io: (input/output) Location to store more output data
2044 * @last: End of output data buffer
2045 * 1949 *
2046 * Generate a generic MODE SENSE control mode page. 1950 * Generate a generic MODE SENSE control mode page.
2047 * 1951 *
2048 * LOCKING: 1952 * LOCKING:
2049 * None. 1953 * None.
2050 */ 1954 */
2051 1955static unsigned int ata_msense_ctl_mode(u8 *buf)
2052static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last)
2053{ 1956{
2054 ata_msense_push(ptr_io, last, def_control_mpage, 1957 memcpy(buf, def_control_mpage, sizeof(def_control_mpage));
2055 sizeof(def_control_mpage));
2056 return sizeof(def_control_mpage); 1958 return sizeof(def_control_mpage);
2057} 1959}
2058 1960
2059/** 1961/**
2060 * ata_msense_rw_recovery - Simulate MODE SENSE r/w error recovery page 1962 * ata_msense_rw_recovery - Simulate MODE SENSE r/w error recovery page
2061 * @dev: Device associated with this MODE SENSE command 1963 * @bufp: output buffer
2062 * @ptr_io: (input/output) Location to store more output data
2063 * @last: End of output data buffer
2064 * 1964 *
2065 * Generate a generic MODE SENSE r/w error recovery page. 1965 * Generate a generic MODE SENSE r/w error recovery page.
2066 * 1966 *
2067 * LOCKING: 1967 * LOCKING:
2068 * None. 1968 * None.
2069 */ 1969 */
2070 1970static unsigned int ata_msense_rw_recovery(u8 *buf)
2071static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
2072{ 1971{
2073 1972 memcpy(buf, def_rw_recovery_mpage, sizeof(def_rw_recovery_mpage));
2074 ata_msense_push(ptr_io, last, def_rw_recovery_mpage,
2075 sizeof(def_rw_recovery_mpage));
2076 return sizeof(def_rw_recovery_mpage); 1973 return sizeof(def_rw_recovery_mpage);
2077} 1974}
2078 1975
@@ -2104,7 +2001,6 @@ static int ata_dev_supports_fua(u16 *id)
2104 * ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands 2001 * ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands
2105 * @args: device IDENTIFY data / SCSI command of interest. 2002 * @args: device IDENTIFY data / SCSI command of interest.
2106 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 2003 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
2107 * @buflen: Response buffer length.
2108 * 2004 *
2109 * Simulate MODE SENSE commands. Assume this is invoked for direct 2005 * Simulate MODE SENSE commands. Assume this is invoked for direct
2110 * access devices (e.g. disks) only. There should be no block 2006 * access devices (e.g. disks) only. There should be no block
@@ -2113,19 +2009,17 @@ static int ata_dev_supports_fua(u16 *id)
2113 * LOCKING: 2009 * LOCKING:
2114 * spin_lock_irqsave(host lock) 2010 * spin_lock_irqsave(host lock)
2115 */ 2011 */
2116 2012static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
2117unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
2118 unsigned int buflen)
2119{ 2013{
2120 struct ata_device *dev = args->dev; 2014 struct ata_device *dev = args->dev;
2121 u8 *scsicmd = args->cmd->cmnd, *p, *last; 2015 u8 *scsicmd = args->cmd->cmnd, *p = rbuf;
2122 const u8 sat_blk_desc[] = { 2016 const u8 sat_blk_desc[] = {
2123 0, 0, 0, 0, /* number of blocks: sat unspecified */ 2017 0, 0, 0, 0, /* number of blocks: sat unspecified */
2124 0, 2018 0,
2125 0, 0x2, 0x0 /* block length: 512 bytes */ 2019 0, 0x2, 0x0 /* block length: 512 bytes */
2126 }; 2020 };
2127 u8 pg, spg; 2021 u8 pg, spg;
2128 unsigned int ebd, page_control, six_byte, output_len, alloc_len, minlen; 2022 unsigned int ebd, page_control, six_byte;
2129 u8 dpofua; 2023 u8 dpofua;
2130 2024
2131 VPRINTK("ENTER\n"); 2025 VPRINTK("ENTER\n");
@@ -2148,17 +2042,10 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
2148 goto invalid_fld; 2042 goto invalid_fld;
2149 } 2043 }
2150 2044
2151 if (six_byte) { 2045 if (six_byte)
2152 output_len = 4 + (ebd ? 8 : 0); 2046 p += 4 + (ebd ? 8 : 0);
2153 alloc_len = scsicmd[4]; 2047 else
2154 } else { 2048 p += 8 + (ebd ? 8 : 0);
2155 output_len = 8 + (ebd ? 8 : 0);
2156 alloc_len = (scsicmd[7] << 8) + scsicmd[8];
2157 }
2158 minlen = (alloc_len < buflen) ? alloc_len : buflen;
2159
2160 p = rbuf + output_len;
2161 last = rbuf + minlen - 1;
2162 2049
2163 pg = scsicmd[2] & 0x3f; 2050 pg = scsicmd[2] & 0x3f;
2164 spg = scsicmd[3]; 2051 spg = scsicmd[3];
@@ -2171,61 +2058,48 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
2171 2058
2172 switch(pg) { 2059 switch(pg) {
2173 case RW_RECOVERY_MPAGE: 2060 case RW_RECOVERY_MPAGE:
2174 output_len += ata_msense_rw_recovery(&p, last); 2061 p += ata_msense_rw_recovery(p);
2175 break; 2062 break;
2176 2063
2177 case CACHE_MPAGE: 2064 case CACHE_MPAGE:
2178 output_len += ata_msense_caching(args->id, &p, last); 2065 p += ata_msense_caching(args->id, p);
2179 break; 2066 break;
2180 2067
2181 case CONTROL_MPAGE: { 2068 case CONTROL_MPAGE:
2182 output_len += ata_msense_ctl_mode(&p, last); 2069 p += ata_msense_ctl_mode(p);
2183 break; 2070 break;
2184 }
2185 2071
2186 case ALL_MPAGES: 2072 case ALL_MPAGES:
2187 output_len += ata_msense_rw_recovery(&p, last); 2073 p += ata_msense_rw_recovery(p);
2188 output_len += ata_msense_caching(args->id, &p, last); 2074 p += ata_msense_caching(args->id, p);
2189 output_len += ata_msense_ctl_mode(&p, last); 2075 p += ata_msense_ctl_mode(p);
2190 break; 2076 break;
2191 2077
2192 default: /* invalid page code */ 2078 default: /* invalid page code */
2193 goto invalid_fld; 2079 goto invalid_fld;
2194 } 2080 }
2195 2081
2196 if (minlen < 1)
2197 return 0;
2198
2199 dpofua = 0; 2082 dpofua = 0;
2200 if (ata_dev_supports_fua(args->id) && (dev->flags & ATA_DFLAG_LBA48) && 2083 if (ata_dev_supports_fua(args->id) && (dev->flags & ATA_DFLAG_LBA48) &&
2201 (!(dev->flags & ATA_DFLAG_PIO) || dev->multi_count)) 2084 (!(dev->flags & ATA_DFLAG_PIO) || dev->multi_count))
2202 dpofua = 1 << 4; 2085 dpofua = 1 << 4;
2203 2086
2204 if (six_byte) { 2087 if (six_byte) {
2205 output_len--; 2088 rbuf[0] = p - rbuf - 1;
2206 rbuf[0] = output_len; 2089 rbuf[2] |= dpofua;
2207 if (minlen > 2)
2208 rbuf[2] |= dpofua;
2209 if (ebd) { 2090 if (ebd) {
2210 if (minlen > 3) 2091 rbuf[3] = sizeof(sat_blk_desc);
2211 rbuf[3] = sizeof(sat_blk_desc); 2092 memcpy(rbuf + 4, sat_blk_desc, sizeof(sat_blk_desc));
2212 if (minlen > 11)
2213 memcpy(rbuf + 4, sat_blk_desc,
2214 sizeof(sat_blk_desc));
2215 } 2093 }
2216 } else { 2094 } else {
2217 output_len -= 2; 2095 unsigned int output_len = p - rbuf - 2;
2096
2218 rbuf[0] = output_len >> 8; 2097 rbuf[0] = output_len >> 8;
2219 if (minlen > 1) 2098 rbuf[1] = output_len;
2220 rbuf[1] = output_len; 2099 rbuf[3] |= dpofua;
2221 if (minlen > 3)
2222 rbuf[3] |= dpofua;
2223 if (ebd) { 2100 if (ebd) {
2224 if (minlen > 7) 2101 rbuf[7] = sizeof(sat_blk_desc);
2225 rbuf[7] = sizeof(sat_blk_desc); 2102 memcpy(rbuf + 8, sat_blk_desc, sizeof(sat_blk_desc));
2226 if (minlen > 15)
2227 memcpy(rbuf + 8, sat_blk_desc,
2228 sizeof(sat_blk_desc));
2229 } 2103 }
2230 } 2104 }
2231 return 0; 2105 return 0;
@@ -2245,15 +2119,13 @@ saving_not_supp:
2245 * ata_scsiop_read_cap - Simulate READ CAPACITY[ 16] commands 2119 * ata_scsiop_read_cap - Simulate READ CAPACITY[ 16] commands
2246 * @args: device IDENTIFY data / SCSI command of interest. 2120 * @args: device IDENTIFY data / SCSI command of interest.
2247 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 2121 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
2248 * @buflen: Response buffer length.
2249 * 2122 *
2250 * Simulate READ CAPACITY commands. 2123 * Simulate READ CAPACITY commands.
2251 * 2124 *
2252 * LOCKING: 2125 * LOCKING:
2253 * None. 2126 * None.
2254 */ 2127 */
2255unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf, 2128static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
2256 unsigned int buflen)
2257{ 2129{
2258 u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */ 2130 u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */
2259 2131
@@ -2264,28 +2136,28 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
2264 last_lba = 0xffffffff; 2136 last_lba = 0xffffffff;
2265 2137
2266 /* sector count, 32-bit */ 2138 /* sector count, 32-bit */
2267 ATA_SCSI_RBUF_SET(0, last_lba >> (8 * 3)); 2139 rbuf[0] = last_lba >> (8 * 3);
2268 ATA_SCSI_RBUF_SET(1, last_lba >> (8 * 2)); 2140 rbuf[1] = last_lba >> (8 * 2);
2269 ATA_SCSI_RBUF_SET(2, last_lba >> (8 * 1)); 2141 rbuf[2] = last_lba >> (8 * 1);
2270 ATA_SCSI_RBUF_SET(3, last_lba); 2142 rbuf[3] = last_lba;
2271 2143
2272 /* sector size */ 2144 /* sector size */
2273 ATA_SCSI_RBUF_SET(6, ATA_SECT_SIZE >> 8); 2145 rbuf[6] = ATA_SECT_SIZE >> 8;
2274 ATA_SCSI_RBUF_SET(7, ATA_SECT_SIZE & 0xff); 2146 rbuf[7] = ATA_SECT_SIZE & 0xff;
2275 } else { 2147 } else {
2276 /* sector count, 64-bit */ 2148 /* sector count, 64-bit */
2277 ATA_SCSI_RBUF_SET(0, last_lba >> (8 * 7)); 2149 rbuf[0] = last_lba >> (8 * 7);
2278 ATA_SCSI_RBUF_SET(1, last_lba >> (8 * 6)); 2150 rbuf[1] = last_lba >> (8 * 6);
2279 ATA_SCSI_RBUF_SET(2, last_lba >> (8 * 5)); 2151 rbuf[2] = last_lba >> (8 * 5);
2280 ATA_SCSI_RBUF_SET(3, last_lba >> (8 * 4)); 2152 rbuf[3] = last_lba >> (8 * 4);
2281 ATA_SCSI_RBUF_SET(4, last_lba >> (8 * 3)); 2153 rbuf[4] = last_lba >> (8 * 3);
2282 ATA_SCSI_RBUF_SET(5, last_lba >> (8 * 2)); 2154 rbuf[5] = last_lba >> (8 * 2);
2283 ATA_SCSI_RBUF_SET(6, last_lba >> (8 * 1)); 2155 rbuf[6] = last_lba >> (8 * 1);
2284 ATA_SCSI_RBUF_SET(7, last_lba); 2156 rbuf[7] = last_lba;
2285 2157
2286 /* sector size */ 2158 /* sector size */
2287 ATA_SCSI_RBUF_SET(10, ATA_SECT_SIZE >> 8); 2159 rbuf[10] = ATA_SECT_SIZE >> 8;
2288 ATA_SCSI_RBUF_SET(11, ATA_SECT_SIZE & 0xff); 2160 rbuf[11] = ATA_SECT_SIZE & 0xff;
2289 } 2161 }
2290 2162
2291 return 0; 2163 return 0;
@@ -2295,16 +2167,13 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
2295 * ata_scsiop_report_luns - Simulate REPORT LUNS command 2167 * ata_scsiop_report_luns - Simulate REPORT LUNS command
2296 * @args: device IDENTIFY data / SCSI command of interest. 2168 * @args: device IDENTIFY data / SCSI command of interest.
2297 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 2169 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
2298 * @buflen: Response buffer length.
2299 * 2170 *
2300 * Simulate REPORT LUNS command. 2171 * Simulate REPORT LUNS command.
2301 * 2172 *
2302 * LOCKING: 2173 * LOCKING:
2303 * spin_lock_irqsave(host lock) 2174 * spin_lock_irqsave(host lock)
2304 */ 2175 */
2305 2176static unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf)
2306unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
2307 unsigned int buflen)
2308{ 2177{
2309 VPRINTK("ENTER\n"); 2178 VPRINTK("ENTER\n");
2310 rbuf[3] = 8; /* just one lun, LUN 0, size 8 bytes */ 2179 rbuf[3] = 8; /* just one lun, LUN 0, size 8 bytes */
@@ -2438,13 +2307,10 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
2438 u8 *scsicmd = cmd->cmnd; 2307 u8 *scsicmd = cmd->cmnd;
2439 2308
2440 if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) { 2309 if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) {
2441 u8 *buf = NULL;
2442 unsigned int buflen;
2443 unsigned long flags; 2310 unsigned long flags;
2311 u8 *buf;
2444 2312
2445 local_irq_save(flags); 2313 buf = ata_scsi_rbuf_get(cmd, true, &flags);
2446
2447 buflen = ata_scsi_rbuf_get(cmd, &buf);
2448 2314
2449 /* ATAPI devices typically report zero for their SCSI version, 2315 /* ATAPI devices typically report zero for their SCSI version,
2450 * and sometimes deviate from the spec WRT response data 2316 * and sometimes deviate from the spec WRT response data
@@ -2459,9 +2325,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
2459 buf[3] = 0x32; 2325 buf[3] = 0x32;
2460 } 2326 }
2461 2327
2462 ata_scsi_rbuf_put(cmd, buf); 2328 ata_scsi_rbuf_put(cmd, true, &flags);
2463
2464 local_irq_restore(flags);
2465 } 2329 }
2466 2330
2467 cmd->result = SAM_STAT_GOOD; 2331 cmd->result = SAM_STAT_GOOD;