Commit | Line | Data |
---|---|---|
a98c5b19 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
af55ff67 MP |
2 | /* |
3 | * sd_dif.c - SCSI Data Integrity Field | |
4 | * | |
5 | * Copyright (C) 2007, 2008 Oracle Corporation | |
6 | * Written by: Martin K. Petersen <martin.petersen@oracle.com> | |
af55ff67 MP |
7 | */ |
8 | ||
fe45e630 | 9 | #include <linux/blk-integrity.h> |
2341c2f8 | 10 | #include <linux/t10-pi.h> |
af55ff67 MP |
11 | |
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> | |
21 | ||
af55ff67 MP |
22 | #include "sd.h" |
23 | ||
af55ff67 MP |
24 | /* |
25 | * Configure exchange of protection information between OS and HBA. | |
26 | */ | |
27 | void sd_dif_config_host(struct scsi_disk *sdkp) | |
28 | { | |
29 | struct scsi_device *sdp = sdkp->device; | |
30 | struct gendisk *disk = sdkp->disk; | |
31 | u8 type = sdkp->protection_type; | |
0f8087ec | 32 | struct blk_integrity bi; |
9e06688e | 33 | int dif, dix; |
af55ff67 | 34 | |
9e06688e MP |
35 | dif = scsi_host_dif_capable(sdp->host, type); |
36 | dix = scsi_host_dix_capable(sdp->host, type); | |
af55ff67 | 37 | |
9e06688e MP |
38 | if (!dix && scsi_host_dix_capable(sdp->host, 0)) { |
39 | dif = 0; dix = 1; | |
40 | } | |
af55ff67 | 41 | |
26a02d97 XY |
42 | if (!dix) { |
43 | blk_integrity_unregister(disk); | |
af55ff67 | 44 | return; |
26a02d97 | 45 | } |
af55ff67 | 46 | |
0f8087ec MP |
47 | memset(&bi, 0, sizeof(bi)); |
48 | ||
af55ff67 | 49 | /* Enable DMA of protection information */ |
aae7df50 | 50 | if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) { |
8475c811 | 51 | if (type == T10_PI_TYPE3_PROTECTION) |
0f8087ec | 52 | bi.profile = &t10_pi_type3_ip; |
af55ff67 | 53 | else |
0f8087ec | 54 | bi.profile = &t10_pi_type1_ip; |
aae7df50 | 55 | |
0f8087ec | 56 | bi.flags |= BLK_INTEGRITY_IP_CHECKSUM; |
aae7df50 | 57 | } else |
8475c811 | 58 | if (type == T10_PI_TYPE3_PROTECTION) |
0f8087ec | 59 | bi.profile = &t10_pi_type3_crc; |
af55ff67 | 60 | else |
0f8087ec | 61 | bi.profile = &t10_pi_type1_crc; |
af55ff67 | 62 | |
0f8087ec | 63 | bi.tuple_size = sizeof(struct t10_pi_tuple); |
af55ff67 | 64 | |
3aec2f41 | 65 | if (dif && type) { |
0f8087ec | 66 | bi.flags |= BLK_INTEGRITY_DEVICE_CAPABLE; |
3aec2f41 | 67 | |
e557990e | 68 | if (!sdkp->ATO) |
0f8087ec | 69 | goto out; |
3aec2f41 | 70 | |
8475c811 | 71 | if (type == T10_PI_TYPE3_PROTECTION) |
0f8087ec | 72 | bi.tag_size = sizeof(u16) + sizeof(u32); |
af55ff67 | 73 | else |
0f8087ec | 74 | bi.tag_size = sizeof(u16); |
af55ff67 | 75 | } |
0f8087ec | 76 | |
26a02d97 XY |
77 | sd_first_printk(KERN_NOTICE, sdkp, |
78 | "Enabling DIX %s, application tag size %u bytes\n", | |
79 | bi.profile->name, bi.tag_size); | |
0f8087ec MP |
80 | out: |
81 | blk_integrity_register(disk, &bi); | |
af55ff67 MP |
82 | } |
83 |