/* * Configure exchange of protection information between OS and HBA. */ 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; dif = scsi_host_dif_capable(sdp->host, type); dix = scsi_host_dix_capable(sdp->host, type); if (!dix && scsi_host_dix_capable(sdp->host, 0)) { dif = 0; dix = 1; } if (!dix) return; /* Enable DMA of protection information */ if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) if (type == SD_DIF_TYPE3_PROTECTION) blk_integrity_register(disk, &dif_type3_integrity_ip); else blk_integrity_register(disk, &dif_type1_integrity_ip); else if (type == SD_DIF_TYPE3_PROTECTION) blk_integrity_register(disk, &dif_type3_integrity_crc); else blk_integrity_register(disk, &dif_type1_integrity_crc); sd_printk(KERN_NOTICE, sdkp, "Enabling DIX %s protection\n", disk->integrity->name); /* Signal to block layer that we support sector tagging */ if (dif && type && sdkp->ATO) { if (type == SD_DIF_TYPE3_PROTECTION) disk->integrity->tag_size = sizeof(u16) + sizeof(u32); else disk->integrity->tag_size = sizeof(u16); sd_printk(KERN_NOTICE, sdkp, "DIF application tag size %u\n", disk->integrity->tag_size); } }
static ssize_t sd_show_protection_mode(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; unsigned int dif, dix; dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type); dix = scsi_host_dix_capable(sdp->host, sdkp->protection_type); if (!dix && scsi_host_dix_capable(sdp->host, SD_DIF_TYPE0_PROTECTION)) { dif = 0; dix = 1; } if (!dif && !dix) return snprintf(buf, 20, "none\n"); return snprintf(buf, 20, "%s%u\n", dix ? "dix" : "dif", dif); }