aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_debug.c')
-rw-r--r--drivers/scsi/scsi_debug.c174
1 files changed, 70 insertions, 104 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index d055450c2a4a..cb4fefa1bfba 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -258,7 +258,7 @@ struct sdebug_queued_cmd {
258static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; 258static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE];
259 259
260static unsigned char * fake_storep; /* ramdisk storage */ 260static unsigned char * fake_storep; /* ramdisk storage */
261static unsigned char *dif_storep; /* protection info */ 261static struct sd_dif_tuple *dif_storep; /* protection info */
262static void *map_storep; /* provisioning map */ 262static void *map_storep; /* provisioning map */
263 263
264static unsigned long map_size; 264static unsigned long map_size;
@@ -277,11 +277,6 @@ static char sdebug_proc_name[] = "scsi_debug";
277 277
278static struct bus_type pseudo_lld_bus; 278static struct bus_type pseudo_lld_bus;
279 279
280static inline sector_t dif_offset(sector_t sector)
281{
282 return sector << 3;
283}
284
285static struct device_driver sdebug_driverfs_driver = { 280static struct device_driver sdebug_driverfs_driver = {
286 .name = sdebug_proc_name, 281 .name = sdebug_proc_name,
287 .bus = &pseudo_lld_bus, 282 .bus = &pseudo_lld_bus,
@@ -1736,6 +1731,50 @@ static int do_device_access(struct scsi_cmnd *scmd,
1736 return ret; 1731 return ret;
1737} 1732}
1738 1733
1734static u16 dif_compute_csum(const void *buf, int len)
1735{
1736 u16 csum;
1737
1738 switch (scsi_debug_guard) {
1739 case 1:
1740 csum = ip_compute_csum(buf, len);
1741 break;
1742 case 0:
1743 csum = cpu_to_be16(crc_t10dif(buf, len));
1744 break;
1745 }
1746 return csum;
1747}
1748
1749static int dif_verify(struct sd_dif_tuple *sdt, const void *data,
1750 sector_t sector, u32 ei_lba)
1751{
1752 u16 csum = dif_compute_csum(data, scsi_debug_sector_size);
1753
1754 if (sdt->guard_tag != csum) {
1755 pr_err("%s: GUARD check failed on sector %lu rcvd 0x%04x, data 0x%04x\n",
1756 __func__,
1757 (unsigned long)sector,
1758 be16_to_cpu(sdt->guard_tag),
1759 be16_to_cpu(csum));
1760 return 0x01;
1761 }
1762 if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
1763 be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) {
1764 pr_err("%s: REF check failed on sector %lu\n",
1765 __func__, (unsigned long)sector);
1766 return 0x03;
1767 }
1768 if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
1769 be32_to_cpu(sdt->ref_tag) != ei_lba) {
1770 pr_err("%s: REF check failed on sector %lu\n",
1771 __func__, (unsigned long)sector);
1772 dif_errors++;
1773 return 0x03;
1774 }
1775 return 0;
1776}
1777
1739static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, 1778static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
1740 unsigned int sectors, u32 ei_lba) 1779 unsigned int sectors, u32 ei_lba)
1741{ 1780{
@@ -1748,71 +1787,38 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
1748 1787
1749 start_sec = do_div(tmp_sec, sdebug_store_sectors); 1788 start_sec = do_div(tmp_sec, sdebug_store_sectors);
1750 1789
1751 sdt = (struct sd_dif_tuple *)(dif_storep + dif_offset(start_sec)); 1790 sdt = dif_storep + start_sec;
1752 1791
1753 for (i = 0 ; i < sectors ; i++) { 1792 for (i = 0 ; i < sectors ; i++) {
1754 u16 csum; 1793 int ret;
1755 1794
1756 if (sdt[i].app_tag == 0xffff) 1795 if (sdt[i].app_tag == 0xffff)
1757 continue; 1796 continue;
1758 1797
1759 sector = start_sec + i; 1798 sector = start_sec + i;
1760 1799
1761 switch (scsi_debug_guard) { 1800 ret = dif_verify(&sdt[i],
1762 case 1: 1801 fake_storep + sector * scsi_debug_sector_size,
1763 csum = ip_compute_csum(fake_storep + 1802 sector, ei_lba);
1764 sector * scsi_debug_sector_size, 1803 if (ret) {
1765 scsi_debug_sector_size);
1766 break;
1767 case 0:
1768 csum = crc_t10dif(fake_storep +
1769 sector * scsi_debug_sector_size,
1770 scsi_debug_sector_size);
1771 csum = cpu_to_be16(csum);
1772 break;
1773 default:
1774 BUG();
1775 }
1776
1777 if (sdt[i].guard_tag != csum) {
1778 printk(KERN_ERR "%s: GUARD check failed on sector %lu" \
1779 " rcvd 0x%04x, data 0x%04x\n", __func__,
1780 (unsigned long)sector,
1781 be16_to_cpu(sdt[i].guard_tag),
1782 be16_to_cpu(csum));
1783 dif_errors++;
1784 return 0x01;
1785 }
1786
1787 if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
1788 be32_to_cpu(sdt[i].ref_tag) != (sector & 0xffffffff)) {
1789 printk(KERN_ERR "%s: REF check failed on sector %lu\n",
1790 __func__, (unsigned long)sector);
1791 dif_errors++; 1804 dif_errors++;
1792 return 0x03; 1805 return ret;
1793 }
1794
1795 if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
1796 be32_to_cpu(sdt[i].ref_tag) != ei_lba) {
1797 printk(KERN_ERR "%s: REF check failed on sector %lu\n",
1798 __func__, (unsigned long)sector);
1799 dif_errors++;
1800 return 0x03;
1801 } 1806 }
1802 1807
1803 ei_lba++; 1808 ei_lba++;
1804 } 1809 }
1805 1810
1806 resid = sectors * 8; /* Bytes of protection data to copy into sgl */ 1811 /* Bytes of protection data to copy into sgl */
1812 resid = sectors * sizeof(*dif_storep);
1807 sector = start_sec; 1813 sector = start_sec;
1808 1814
1809 scsi_for_each_prot_sg(SCpnt, psgl, scsi_prot_sg_count(SCpnt), i) { 1815 scsi_for_each_prot_sg(SCpnt, psgl, scsi_prot_sg_count(SCpnt), i) {
1810 int len = min(psgl->length, resid); 1816 int len = min(psgl->length, resid);
1811 1817
1812 paddr = kmap_atomic(sg_page(psgl)) + psgl->offset; 1818 paddr = kmap_atomic(sg_page(psgl)) + psgl->offset;
1813 memcpy(paddr, dif_storep + dif_offset(sector), len); 1819 memcpy(paddr, dif_storep + sector, len);
1814 1820
1815 sector += len >> 3; 1821 sector += len / sizeof(*dif_storep);
1816 if (sector >= sdebug_store_sectors) { 1822 if (sector >= sdebug_store_sectors) {
1817 /* Force wrap */ 1823 /* Force wrap */
1818 tmp_sec = sector; 1824 tmp_sec = sector;
@@ -1910,22 +1916,21 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
1910 sector_t tmp_sec = start_sec; 1916 sector_t tmp_sec = start_sec;
1911 sector_t sector; 1917 sector_t sector;
1912 int ppage_offset; 1918 int ppage_offset;
1913 unsigned short csum;
1914 1919
1915 sector = do_div(tmp_sec, sdebug_store_sectors); 1920 sector = do_div(tmp_sec, sdebug_store_sectors);
1916 1921
1917 BUG_ON(scsi_sg_count(SCpnt) == 0); 1922 BUG_ON(scsi_sg_count(SCpnt) == 0);
1918 BUG_ON(scsi_prot_sg_count(SCpnt) == 0); 1923 BUG_ON(scsi_prot_sg_count(SCpnt) == 0);
1919 1924
1920 paddr = kmap_atomic(sg_page(psgl)) + psgl->offset;
1921 ppage_offset = 0; 1925 ppage_offset = 0;
1922 1926
1923 /* For each data page */ 1927 /* For each data page */
1924 scsi_for_each_sg(SCpnt, dsgl, scsi_sg_count(SCpnt), i) { 1928 scsi_for_each_sg(SCpnt, dsgl, scsi_sg_count(SCpnt), i) {
1925 daddr = kmap_atomic(sg_page(dsgl)) + dsgl->offset; 1929 daddr = kmap_atomic(sg_page(dsgl)) + dsgl->offset;
1930 paddr = kmap_atomic(sg_page(psgl)) + psgl->offset;
1926 1931
1927 /* For each sector-sized chunk in data page */ 1932 /* For each sector-sized chunk in data page */
1928 for (j = 0 ; j < dsgl->length ; j += scsi_debug_sector_size) { 1933 for (j = 0; j < dsgl->length; j += scsi_debug_sector_size) {
1929 1934
1930 /* If we're at the end of the current 1935 /* If we're at the end of the current
1931 * protection page advance to the next one 1936 * protection page advance to the next one
@@ -1941,51 +1946,9 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
1941 1946
1942 sdt = paddr + ppage_offset; 1947 sdt = paddr + ppage_offset;
1943 1948
1944 switch (scsi_debug_guard) { 1949 ret = dif_verify(sdt, daddr + j, start_sec, ei_lba);
1945 case 1: 1950 if (ret) {
1946 csum = ip_compute_csum(daddr, 1951 dump_sector(daddr + j, scsi_debug_sector_size);
1947 scsi_debug_sector_size);
1948 break;
1949 case 0:
1950 csum = cpu_to_be16(crc_t10dif(daddr,
1951 scsi_debug_sector_size));
1952 break;
1953 default:
1954 BUG();
1955 ret = 0;
1956 goto out;
1957 }
1958
1959 if (sdt->guard_tag != csum) {
1960 printk(KERN_ERR
1961 "%s: GUARD check failed on sector %lu " \
1962 "rcvd 0x%04x, calculated 0x%04x\n",
1963 __func__, (unsigned long)sector,
1964 be16_to_cpu(sdt->guard_tag),
1965 be16_to_cpu(csum));
1966 ret = 0x01;
1967 dump_sector(daddr, scsi_debug_sector_size);
1968 goto out;
1969 }
1970
1971 if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
1972 be32_to_cpu(sdt->ref_tag)
1973 != (start_sec & 0xffffffff)) {
1974 printk(KERN_ERR
1975 "%s: REF check failed on sector %lu\n",
1976 __func__, (unsigned long)sector);
1977 ret = 0x03;
1978 dump_sector(daddr, scsi_debug_sector_size);
1979 goto out;
1980 }
1981
1982 if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
1983 be32_to_cpu(sdt->ref_tag) != ei_lba) {
1984 printk(KERN_ERR
1985 "%s: REF check failed on sector %lu\n",
1986 __func__, (unsigned long)sector);
1987 ret = 0x03;
1988 dump_sector(daddr, scsi_debug_sector_size);
1989 goto out; 1952 goto out;
1990 } 1953 }
1991 1954
@@ -1994,7 +1957,7 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
1994 * correctness we need to verify each sector 1957 * correctness we need to verify each sector
1995 * before writing it to "stable" storage 1958 * before writing it to "stable" storage
1996 */ 1959 */
1997 memcpy(dif_storep + dif_offset(sector), sdt, 8); 1960 memcpy(dif_storep + sector, sdt, sizeof(*sdt));
1998 1961
1999 sector++; 1962 sector++;
2000 1963
@@ -2003,23 +1966,21 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
2003 1966
2004 start_sec++; 1967 start_sec++;
2005 ei_lba++; 1968 ei_lba++;
2006 daddr += scsi_debug_sector_size;
2007 ppage_offset += sizeof(struct sd_dif_tuple); 1969 ppage_offset += sizeof(struct sd_dif_tuple);
2008 } 1970 }
2009 1971
1972 kunmap_atomic(paddr);
2010 kunmap_atomic(daddr); 1973 kunmap_atomic(daddr);
2011 } 1974 }
2012 1975
2013 kunmap_atomic(paddr);
2014
2015 dix_writes++; 1976 dix_writes++;
2016 1977
2017 return 0; 1978 return 0;
2018 1979
2019out: 1980out:
2020 dif_errors++; 1981 dif_errors++;
2021 kunmap_atomic(daddr);
2022 kunmap_atomic(paddr); 1982 kunmap_atomic(paddr);
1983 kunmap_atomic(daddr);
2023 return ret; 1984 return ret;
2024} 1985}
2025 1986
@@ -2092,6 +2053,11 @@ static void unmap_region(sector_t lba, unsigned int len)
2092 scsi_debug_sector_size * 2053 scsi_debug_sector_size *
2093 scsi_debug_unmap_granularity); 2054 scsi_debug_unmap_granularity);
2094 } 2055 }
2056 if (dif_storep) {
2057 memset(dif_storep + lba, 0xff,
2058 sizeof(*dif_storep) *
2059 scsi_debug_unmap_granularity);
2060 }
2095 } 2061 }
2096 lba = map_index_to_lba(index + 1); 2062 lba = map_index_to_lba(index + 1);
2097 } 2063 }
@@ -3400,7 +3366,7 @@ static int __init scsi_debug_init(void)
3400 if (scsi_debug_num_parts > 0) 3366 if (scsi_debug_num_parts > 0)
3401 sdebug_build_parts(fake_storep, sz); 3367 sdebug_build_parts(fake_storep, sz);
3402 3368
3403 if (scsi_debug_dif) { 3369 if (scsi_debug_dix) {
3404 int dif_size; 3370 int dif_size;
3405 3371
3406 dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple); 3372 dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple);