1 // SPDX-License-Identifier: GPL-2.0-only
3 * sd_dif.c - SCSI Data Integrity Field
5 * Copyright (C) 2007, 2008 Oracle Corporation
6 * Written by: Martin K. Petersen <martin.petersen@oracle.com>
9 #include <linux/blkdev.h>
10 #include <linux/t10-pi.h>
12 #include <scsi/scsi.h>
13 #include <scsi/scsi_cmnd.h>
14 #include <scsi/scsi_dbg.h>
15 #include <scsi/scsi_device.h>
16 #include <scsi/scsi_driver.h>
17 #include <scsi/scsi_eh.h>
18 #include <scsi/scsi_host.h>
19 #include <scsi/scsi_ioctl.h>
20 #include <scsi/scsicam.h>
25 * Configure exchange of protection information between OS and HBA.
27 void sd_dif_config_host(struct scsi_disk
*sdkp
)
29 struct scsi_device
*sdp
= sdkp
->device
;
30 struct gendisk
*disk
= sdkp
->disk
;
31 u8 type
= sdkp
->protection_type
;
32 struct blk_integrity bi
;
35 dif
= scsi_host_dif_capable(sdp
->host
, type
);
36 dix
= scsi_host_dix_capable(sdp
->host
, type
);
38 if (!dix
&& scsi_host_dix_capable(sdp
->host
, 0)) {
45 memset(&bi
, 0, sizeof(bi
));
47 /* Enable DMA of protection information */
48 if (scsi_host_get_guard(sdkp
->device
->host
) & SHOST_DIX_GUARD_IP
) {
49 if (type
== T10_PI_TYPE3_PROTECTION
)
50 bi
.profile
= &t10_pi_type3_ip
;
52 bi
.profile
= &t10_pi_type1_ip
;
54 bi
.flags
|= BLK_INTEGRITY_IP_CHECKSUM
;
56 if (type
== T10_PI_TYPE3_PROTECTION
)
57 bi
.profile
= &t10_pi_type3_crc
;
59 bi
.profile
= &t10_pi_type1_crc
;
61 bi
.tuple_size
= sizeof(struct t10_pi_tuple
);
62 sd_printk(KERN_NOTICE
, sdkp
,
63 "Enabling DIX %s protection\n", bi
.profile
->name
);
66 bi
.flags
|= BLK_INTEGRITY_DEVICE_CAPABLE
;
71 if (type
== T10_PI_TYPE3_PROTECTION
)
72 bi
.tag_size
= sizeof(u16
) + sizeof(u32
);
74 bi
.tag_size
= sizeof(u16
);
76 sd_printk(KERN_NOTICE
, sdkp
, "DIF application tag size %u\n",
81 blk_integrity_register(disk
, &bi
);