0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/blk-integrity.h>
0010 #include <linux/t10-pi.h>
0011
0012 #include <scsi/scsi.h>
0013 #include <scsi/scsi_cmnd.h>
0014 #include <scsi/scsi_dbg.h>
0015 #include <scsi/scsi_device.h>
0016 #include <scsi/scsi_driver.h>
0017 #include <scsi/scsi_eh.h>
0018 #include <scsi/scsi_host.h>
0019 #include <scsi/scsi_ioctl.h>
0020 #include <scsi/scsicam.h>
0021
0022 #include "sd.h"
0023
0024
0025
0026
0027 void sd_dif_config_host(struct scsi_disk *sdkp)
0028 {
0029 struct scsi_device *sdp = sdkp->device;
0030 struct gendisk *disk = sdkp->disk;
0031 u8 type = sdkp->protection_type;
0032 struct blk_integrity bi;
0033 int dif, dix;
0034
0035 dif = scsi_host_dif_capable(sdp->host, type);
0036 dix = scsi_host_dix_capable(sdp->host, type);
0037
0038 if (!dix && scsi_host_dix_capable(sdp->host, 0)) {
0039 dif = 0; dix = 1;
0040 }
0041
0042 if (!dix)
0043 return;
0044
0045 memset(&bi, 0, sizeof(bi));
0046
0047
0048 if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) {
0049 if (type == T10_PI_TYPE3_PROTECTION)
0050 bi.profile = &t10_pi_type3_ip;
0051 else
0052 bi.profile = &t10_pi_type1_ip;
0053
0054 bi.flags |= BLK_INTEGRITY_IP_CHECKSUM;
0055 } else
0056 if (type == T10_PI_TYPE3_PROTECTION)
0057 bi.profile = &t10_pi_type3_crc;
0058 else
0059 bi.profile = &t10_pi_type1_crc;
0060
0061 bi.tuple_size = sizeof(struct t10_pi_tuple);
0062
0063 if (dif && type) {
0064 bi.flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
0065
0066 if (!sdkp->ATO)
0067 goto out;
0068
0069 if (type == T10_PI_TYPE3_PROTECTION)
0070 bi.tag_size = sizeof(u16) + sizeof(u32);
0071 else
0072 bi.tag_size = sizeof(u16);
0073 }
0074
0075 sd_printk(KERN_NOTICE, sdkp,
0076 "Enabling DIX %s, application tag size %u bytes\n",
0077 bi.profile->name, bi.tag_size);
0078 out:
0079 blk_integrity_register(disk, &bi);
0080 }
0081