diff options
-rw-r--r-- | drivers/scsi/scsi_debug.c | 137 |
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 | ||
1713 | static 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 | |||
1728 | static 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 | |||
1713 | static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, | 1757 | static 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 | } |