aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/scsi_debug.c137
1 files changed, 52 insertions, 85 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index fc8b3aa083d4..3f096a6681ac 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -1710,6 +1710,50 @@ static int do_device_access(struct scsi_cmnd *scmd,
1710 return ret; 1710 return ret;
1711} 1711}
1712 1712
1713static u16 dif_compute_csum(const void *buf, int len)
1714{
1715 u16 csum;
1716
1717 switch (scsi_debug_guard) {
1718 case 1:
1719 csum = ip_compute_csum(buf, len);
1720 break;
1721 case 0:
1722 csum = cpu_to_be16(crc_t10dif(buf, len));
1723 break;
1724 }
1725 return csum;
1726}
1727
1728static int dif_verify(struct sd_dif_tuple *sdt, const void *data,
1729 sector_t sector, u32 ei_lba)
1730{
1731 u16 csum = dif_compute_csum(data, scsi_debug_sector_size);
1732
1733 if (sdt->guard_tag != csum) {
1734 pr_err("%s: GUARD check failed on sector %lu rcvd 0x%04x, data 0x%04x\n",
1735 __func__,
1736 (unsigned long)sector,
1737 be16_to_cpu(sdt->guard_tag),
1738 be16_to_cpu(csum));
1739 return 0x01;
1740 }
1741 if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
1742 be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) {
1743 pr_err("%s: REF check failed on sector %lu\n",
1744 __func__, (unsigned long)sector);
1745 return 0x03;
1746 }
1747 if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
1748 be32_to_cpu(sdt->ref_tag) != ei_lba) {
1749 pr_err("%s: REF check failed on sector %lu\n",
1750 __func__, (unsigned long)sector);
1751 dif_errors++;
1752 return 0x03;
1753 }
1754 return 0;
1755}
1756
1713static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, 1757static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
1714 unsigned int sectors, u32 ei_lba) 1758 unsigned int sectors, u32 ei_lba)
1715{ 1759{
@@ -1725,53 +1769,19 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
1725 sdt = dif_storep + start_sec; 1769 sdt = dif_storep + start_sec;
1726 1770
1727 for (i = 0 ; i < sectors ; i++) { 1771 for (i = 0 ; i < sectors ; i++) {
1728 u16 csum; 1772 int ret;
1729 1773
1730 if (sdt[i].app_tag == 0xffff) 1774 if (sdt[i].app_tag == 0xffff)
1731 continue; 1775 continue;
1732 1776
1733 sector = start_sec + i; 1777 sector = start_sec + i;
1734 1778
1735 switch (scsi_debug_guard) { 1779 ret = dif_verify(&sdt[i],
1736 case 1: 1780 fake_storep + sector * scsi_debug_sector_size,
1737 csum = ip_compute_csum(fake_storep + 1781 sector, ei_lba);
1738 sector * scsi_debug_sector_size, 1782 if (ret) {
1739 scsi_debug_sector_size);
1740 break;
1741 case 0:
1742 csum = crc_t10dif(fake_storep +
1743 sector * scsi_debug_sector_size,
1744 scsi_debug_sector_size);
1745 csum = cpu_to_be16(csum);
1746 break;
1747 default:
1748 BUG();
1749 }
1750
1751 if (sdt[i].guard_tag != csum) {
1752 printk(KERN_ERR "%s: GUARD check failed on sector %lu" \
1753 " rcvd 0x%04x, data 0x%04x\n", __func__,
1754 (unsigned long)sector,
1755 be16_to_cpu(sdt[i].guard_tag),
1756 be16_to_cpu(csum));
1757 dif_errors++;
1758 return 0x01;
1759 }
1760
1761 if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
1762 be32_to_cpu(sdt[i].ref_tag) != (sector & 0xffffffff)) {
1763 printk(KERN_ERR "%s: REF check failed on sector %lu\n",
1764 __func__, (unsigned long)sector);
1765 dif_errors++;
1766 return 0x03;
1767 }
1768
1769 if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
1770 be32_to_cpu(sdt[i].ref_tag) != ei_lba) {
1771 printk(KERN_ERR "%s: REF check failed on sector %lu\n",
1772 __func__, (unsigned long)sector);
1773 dif_errors++; 1783 dif_errors++;
1774 return 0x03; 1784 return ret;
1775 } 1785 }
1776 1786
1777 ei_lba++; 1787 ei_lba++;
@@ -1880,7 +1890,6 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
1880 sector_t tmp_sec = start_sec; 1890 sector_t tmp_sec = start_sec;
1881 sector_t sector; 1891 sector_t sector;
1882 int ppage_offset; 1892 int ppage_offset;
1883 unsigned short csum;
1884 1893
1885 sector = do_div(tmp_sec, sdebug_store_sectors); 1894 sector = do_div(tmp_sec, sdebug_store_sectors);
1886 1895
@@ -1911,50 +1920,8 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
1911 1920
1912 sdt = paddr + ppage_offset; 1921 sdt = paddr + ppage_offset;
1913 1922
1914 switch (scsi_debug_guard) { 1923 ret = dif_verify(sdt, daddr + j, start_sec, ei_lba);
1915 case 1: 1924 if (ret) {
1916 csum = ip_compute_csum(daddr + j,
1917 scsi_debug_sector_size);
1918 break;
1919 case 0:
1920 csum = cpu_to_be16(crc_t10dif(daddr + j,
1921 scsi_debug_sector_size));
1922 break;
1923 default:
1924 BUG();
1925 ret = 0;
1926 goto out;
1927 }
1928
1929 if (sdt->guard_tag != csum) {
1930 printk(KERN_ERR
1931 "%s: GUARD check failed on sector %lu " \
1932 "rcvd 0x%04x, calculated 0x%04x\n",
1933 __func__, (unsigned long)sector,
1934 be16_to_cpu(sdt->guard_tag),
1935 be16_to_cpu(csum));
1936 ret = 0x01;
1937 dump_sector(daddr + j, scsi_debug_sector_size);
1938 goto out;
1939 }
1940
1941 if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
1942 be32_to_cpu(sdt->ref_tag)
1943 != (start_sec & 0xffffffff)) {
1944 printk(KERN_ERR
1945 "%s: REF check failed on sector %lu\n",
1946 __func__, (unsigned long)sector);
1947 ret = 0x03;
1948 dump_sector(daddr + j, scsi_debug_sector_size);
1949 goto out;
1950 }
1951
1952 if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
1953 be32_to_cpu(sdt->ref_tag) != ei_lba) {
1954 printk(KERN_ERR
1955 "%s: REF check failed on sector %lu\n",
1956 __func__, (unsigned long)sector);
1957 ret = 0x03;
1958 dump_sector(daddr + j, scsi_debug_sector_size); 1925 dump_sector(daddr + j, scsi_debug_sector_size);
1959 goto out; 1926 goto out;
1960 } 1927 }