diff options
Diffstat (limited to 'drivers/scsi/sd_dif.c')
-rw-r--r-- | drivers/scsi/sd_dif.c | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c index 943fde7e7ff..194c7706083 100644 --- a/drivers/scsi/sd_dif.c +++ b/drivers/scsi/sd_dif.c @@ -311,24 +311,26 @@ void sd_dif_config_host(struct scsi_disk *sdkp) struct scsi_device *sdp = sdkp->device; struct gendisk *disk = sdkp->disk; u8 type = sdkp->protection_type; + int dif, dix; - /* If this HBA doesn't support DIX, resort to normal I/O or DIF */ - if (scsi_host_dix_capable(sdp->host, type) == 0) { + dif = scsi_host_dif_capable(sdp->host, type); + dix = scsi_host_dix_capable(sdp->host, type); - if (type == SD_DIF_TYPE0_PROTECTION) - return; - - if (scsi_host_dif_capable(sdp->host, type) == 0) { - sd_printk(KERN_INFO, sdkp, "Type %d protection " \ - "unsupported by HBA. Disabling DIF.\n", type); - return; - } + if (!dix && scsi_host_dix_capable(sdp->host, 0)) { + dif = 0; dix = 1; + } - sd_printk(KERN_INFO, sdkp, "Enabling DIF Type %d protection\n", - type); + if (type) { + if (dif) + sd_printk(KERN_INFO, sdkp, + "Enabling DIF Type %d protection\n", type); + else + sd_printk(KERN_INFO, sdkp, + "Disabling DIF Type %d protection\n", type); + } + if (!dix) return; - } /* Enable DMA of protection information */ if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) @@ -343,10 +345,10 @@ void sd_dif_config_host(struct scsi_disk *sdkp) blk_integrity_register(disk, &dif_type1_integrity_crc); sd_printk(KERN_INFO, sdkp, - "Enabling %s integrity protection\n", disk->integrity->name); + "Enabling DIX %s protection\n", disk->integrity->name); /* Signal to block layer that we support sector tagging */ - if (type && sdkp->ATO) { + if (dif && type && sdkp->ATO) { if (type == SD_DIF_TYPE3_PROTECTION) disk->integrity->tag_size = sizeof(u16) + sizeof(u32); else @@ -360,7 +362,7 @@ void sd_dif_config_host(struct scsi_disk *sdkp) /* * DIF DMA operation magic decoder ring. */ -void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix) +void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix, unsigned int type) { int csum_convert, prot_op; @@ -405,7 +407,8 @@ void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix) } scsi_set_prot_op(scmd, prot_op); - scsi_set_prot_type(scmd, dif); + if (dif) + scsi_set_prot_type(scmd, type); } /* |