Commit 4469f9878059f1707f021512e6b34252c4096ee7
Committed by
James Bottomley
1 parent
7c32c7a2d3
Exists in
master
and in
4 other branches
[SCSI] Host protection capabilities
Controllers that support protection information must indicate this to the SCSI midlayer so that the ULD can prepare scsi_cmnds accordingly. This patch implements a host mask and various types of protection: - DIF Type 1-3 (between HBA and disk) - DIX Type 0-3 (between OS and HBA) The patch also allows the HBA to set the guard type to something different than the T10-mandated CRC. Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Showing 2 changed files with 88 additions and 0 deletions Side-by-side Diff
drivers/scsi/scsi_sysfs.c
... | ... | @@ -249,6 +249,8 @@ |
249 | 249 | shost_rd_attr(can_queue, "%hd\n"); |
250 | 250 | shost_rd_attr(sg_tablesize, "%hu\n"); |
251 | 251 | shost_rd_attr(unchecked_isa_dma, "%d\n"); |
252 | +shost_rd_attr(prot_capabilities, "%u\n"); | |
253 | +shost_rd_attr(prot_guard_type, "%hd\n"); | |
252 | 254 | shost_rd_attr2(proc_name, hostt->proc_name, "%s\n"); |
253 | 255 | |
254 | 256 | static struct attribute *scsi_sysfs_shost_attrs[] = { |
... | ... | @@ -263,6 +265,8 @@ |
263 | 265 | &dev_attr_hstate.attr, |
264 | 266 | &dev_attr_supported_mode.attr, |
265 | 267 | &dev_attr_active_mode.attr, |
268 | + &dev_attr_prot_capabilities.attr, | |
269 | + &dev_attr_prot_guard_type.attr, | |
266 | 270 | NULL |
267 | 271 | }; |
268 | 272 |
include/scsi/scsi_host.h
... | ... | @@ -636,6 +636,10 @@ |
636 | 636 | */ |
637 | 637 | unsigned int max_host_blocked; |
638 | 638 | |
639 | + /* Protection Information */ | |
640 | + unsigned int prot_capabilities; | |
641 | + unsigned char prot_guard_type; | |
642 | + | |
639 | 643 | /* |
640 | 644 | * q used for scsi_tgt msgs, async events or any other requests that |
641 | 645 | * need to be processed in userspace |
... | ... | @@ -755,6 +759,86 @@ |
755 | 759 | */ |
756 | 760 | extern void scsi_free_host_dev(struct scsi_device *); |
757 | 761 | extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *); |
762 | + | |
763 | +/* | |
764 | + * DIF defines the exchange of protection information between | |
765 | + * initiator and SBC block device. | |
766 | + * | |
767 | + * DIX defines the exchange of protection information between OS and | |
768 | + * initiator. | |
769 | + */ | |
770 | +enum scsi_host_prot_capabilities { | |
771 | + SHOST_DIF_TYPE1_PROTECTION = 1 << 0, /* T10 DIF Type 1 */ | |
772 | + SHOST_DIF_TYPE2_PROTECTION = 1 << 1, /* T10 DIF Type 2 */ | |
773 | + SHOST_DIF_TYPE3_PROTECTION = 1 << 2, /* T10 DIF Type 3 */ | |
774 | + | |
775 | + SHOST_DIX_TYPE0_PROTECTION = 1 << 3, /* DIX between OS and HBA only */ | |
776 | + SHOST_DIX_TYPE1_PROTECTION = 1 << 4, /* DIX with DIF Type 1 */ | |
777 | + SHOST_DIX_TYPE2_PROTECTION = 1 << 5, /* DIX with DIF Type 2 */ | |
778 | + SHOST_DIX_TYPE3_PROTECTION = 1 << 6, /* DIX with DIF Type 3 */ | |
779 | +}; | |
780 | + | |
781 | +/* | |
782 | + * SCSI hosts which support the Data Integrity Extensions must | |
783 | + * indicate their capabilities by setting the prot_capabilities using | |
784 | + * this call. | |
785 | + */ | |
786 | +static inline void scsi_host_set_prot(struct Scsi_Host *shost, unsigned int mask) | |
787 | +{ | |
788 | + shost->prot_capabilities = mask; | |
789 | +} | |
790 | + | |
791 | +static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost) | |
792 | +{ | |
793 | + return shost->prot_capabilities; | |
794 | +} | |
795 | + | |
796 | +static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type) | |
797 | +{ | |
798 | + switch (target_type) { | |
799 | + case 1: return shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION; | |
800 | + case 2: return shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION; | |
801 | + case 3: return shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION; | |
802 | + } | |
803 | + | |
804 | + return 0; | |
805 | +} | |
806 | + | |
807 | +static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type) | |
808 | +{ | |
809 | + switch (target_type) { | |
810 | + case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION; | |
811 | + case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION; | |
812 | + case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION; | |
813 | + case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION; | |
814 | + } | |
815 | + | |
816 | + return 0; | |
817 | +} | |
818 | + | |
819 | +/* | |
820 | + * All DIX-capable initiators must support the T10-mandated CRC | |
821 | + * checksum. Controllers can optionally implement the IP checksum | |
822 | + * scheme which has much lower impact on system performance. Note | |
823 | + * that the main rationale for the checksum is to match integrity | |
824 | + * metadata with data. Detecting bit errors are a job for ECC memory | |
825 | + * and buses. | |
826 | + */ | |
827 | + | |
828 | +enum scsi_host_guard_type { | |
829 | + SHOST_DIX_GUARD_CRC = 1 << 0, | |
830 | + SHOST_DIX_GUARD_IP = 1 << 1, | |
831 | +}; | |
832 | + | |
833 | +static inline void scsi_host_set_guard(struct Scsi_Host *shost, unsigned char type) | |
834 | +{ | |
835 | + shost->prot_guard_type = type; | |
836 | +} | |
837 | + | |
838 | +static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost) | |
839 | +{ | |
840 | + return shost->prot_guard_type; | |
841 | +} | |
758 | 842 | |
759 | 843 | /* legacy interfaces */ |
760 | 844 | extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); |