diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e04c302fa4f7..12f6fdfc1147 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1693,34 +1693,42 @@ sd_spinup_disk(struct scsi_disk *sdkp) | |||
1693 | /* | 1693 | /* |
1694 | * Determine whether disk supports Data Integrity Field. | 1694 | * Determine whether disk supports Data Integrity Field. |
1695 | */ | 1695 | */ |
1696 | static void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer) | 1696 | static int sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer) |
1697 | { | 1697 | { |
1698 | struct scsi_device *sdp = sdkp->device; | 1698 | struct scsi_device *sdp = sdkp->device; |
1699 | u8 type; | 1699 | u8 type; |
1700 | int ret = 0; | ||
1700 | 1701 | ||
1701 | if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) | 1702 | if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) |
1702 | return; | 1703 | return ret; |
1703 | 1704 | ||
1704 | type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ | 1705 | type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ |
1705 | 1706 | ||
1706 | if (type == sdkp->protection_type || !sdkp->first_scan) | 1707 | if (type > SD_DIF_TYPE3_PROTECTION) |
1707 | return; | 1708 | ret = -ENODEV; |
1709 | else if (scsi_host_dif_capable(sdp->host, type)) | ||
1710 | ret = 1; | ||
1711 | |||
1712 | if (sdkp->first_scan || type != sdkp->protection_type) | ||
1713 | switch (ret) { | ||
1714 | case -ENODEV: | ||
1715 | sd_printk(KERN_ERR, sdkp, "formatted with unsupported" \ | ||
1716 | " protection type %u. Disabling disk!\n", | ||
1717 | type); | ||
1718 | break; | ||
1719 | case 1: | ||
1720 | sd_printk(KERN_NOTICE, sdkp, | ||
1721 | "Enabling DIF Type %u protection\n", type); | ||
1722 | break; | ||
1723 | case 0: | ||
1724 | sd_printk(KERN_NOTICE, sdkp, | ||
1725 | "Disabling DIF Type %u protection\n", type); | ||
1726 | break; | ||
1727 | } | ||
1708 | 1728 | ||
1709 | sdkp->protection_type = type; | 1729 | sdkp->protection_type = type; |
1710 | 1730 | ||
1711 | if (type > SD_DIF_TYPE3_PROTECTION) { | 1731 | return ret; |
1712 | sd_printk(KERN_ERR, sdkp, "formatted with unsupported " \ | ||
1713 | "protection type %u. Disabling disk!\n", type); | ||
1714 | sdkp->capacity = 0; | ||
1715 | return; | ||
1716 | } | ||
1717 | |||
1718 | if (scsi_host_dif_capable(sdp->host, type)) | ||
1719 | sd_printk(KERN_NOTICE, sdkp, | ||
1720 | "Enabling DIF Type %u protection\n", type); | ||
1721 | else | ||
1722 | sd_printk(KERN_NOTICE, sdkp, | ||
1723 | "Disabling DIF Type %u protection\n", type); | ||
1724 | } | 1732 | } |
1725 | 1733 | ||
1726 | static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, | 1734 | static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, |
@@ -1816,7 +1824,10 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, | |||
1816 | sector_size = get_unaligned_be32(&buffer[8]); | 1824 | sector_size = get_unaligned_be32(&buffer[8]); |
1817 | lba = get_unaligned_be64(&buffer[0]); | 1825 | lba = get_unaligned_be64(&buffer[0]); |
1818 | 1826 | ||
1819 | sd_read_protection_type(sdkp, buffer); | 1827 | if (sd_read_protection_type(sdkp, buffer) < 0) { |
1828 | sdkp->capacity = 0; | ||
1829 | return -ENODEV; | ||
1830 | } | ||
1820 | 1831 | ||
1821 | if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) { | 1832 | if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) { |
1822 | sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " | 1833 | sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " |
@@ -2654,7 +2665,8 @@ static void sd_probe_async(void *data, async_cookie_t cookie) | |||
2654 | } | 2665 | } |
2655 | 2666 | ||
2656 | add_disk(gd); | 2667 | add_disk(gd); |
2657 | sd_dif_config_host(sdkp); | 2668 | if (sdkp->capacity) |
2669 | sd_dif_config_host(sdkp); | ||
2658 | 2670 | ||
2659 | sd_revalidate_disk(gd); | 2671 | sd_revalidate_disk(gd); |
2660 | 2672 | ||