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 | */ | |
c6e56cf6 | 27 | void sd_dif_config_host(struct scsi_disk *sdkp, struct queue_limits *lim) |
af55ff67 MP |
28 | { |
29 | struct scsi_device *sdp = sdkp->device; | |
af55ff67 | 30 | u8 type = sdkp->protection_type; |
c6e56cf6 | 31 | struct blk_integrity *bi = &lim->integrity; |
9e06688e | 32 | int dif, dix; |
af55ff67 | 33 | |
c6e56cf6 CH |
34 | memset(bi, 0, sizeof(*bi)); |
35 | ||
9e06688e MP |
36 | dif = scsi_host_dif_capable(sdp->host, type); |
37 | dix = scsi_host_dix_capable(sdp->host, type); | |
af55ff67 | 38 | |
9e06688e MP |
39 | if (!dix && scsi_host_dix_capable(sdp->host, 0)) { |
40 | dif = 0; dix = 1; | |
41 | } | |
af55ff67 | 42 | |
c6e56cf6 | 43 | if (!dix) |
af55ff67 | 44 | return; |
0f8087ec | 45 | |
af55ff67 | 46 | /* Enable DMA of protection information */ |
e9f5f44a | 47 | if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) |
c6e56cf6 | 48 | bi->csum_type = BLK_INTEGRITY_CSUM_IP; |
e9f5f44a | 49 | else |
c6e56cf6 | 50 | bi->csum_type = BLK_INTEGRITY_CSUM_CRC; |
aae7df50 | 51 | |
e9f5f44a | 52 | if (type != T10_PI_TYPE3_PROTECTION) |
c6e56cf6 | 53 | bi->flags |= BLK_INTEGRITY_REF_TAG; |
af55ff67 | 54 | |
c6e56cf6 | 55 | bi->tuple_size = sizeof(struct t10_pi_tuple); |
af55ff67 | 56 | |
3aec2f41 | 57 | if (dif && type) { |
c6e56cf6 | 58 | bi->flags |= BLK_INTEGRITY_DEVICE_CAPABLE; |
3aec2f41 | 59 | |
e557990e | 60 | if (!sdkp->ATO) |
c6e56cf6 | 61 | return; |
3aec2f41 | 62 | |
8475c811 | 63 | if (type == T10_PI_TYPE3_PROTECTION) |
c6e56cf6 | 64 | bi->tag_size = sizeof(u16) + sizeof(u32); |
af55ff67 | 65 | else |
c6e56cf6 | 66 | bi->tag_size = sizeof(u16); |
af55ff67 | 67 | } |
0f8087ec | 68 | |
26a02d97 XY |
69 | sd_first_printk(KERN_NOTICE, sdkp, |
70 | "Enabling DIX %s, application tag size %u bytes\n", | |
c6e56cf6 | 71 | blk_integrity_profile_name(bi), bi->tag_size); |
af55ff67 | 72 | } |