diff options
author | Martin K. Petersen <martin.petersen@oracle.com> | 2008-07-17 04:28:30 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-07-26 15:14:54 -0400 |
commit | 4469f9878059f1707f021512e6b34252c4096ee7 (patch) | |
tree | 3bc8ea358bea85235a8d9691c8b999626e685e0d /include/scsi | |
parent | 7c32c7a2d36c52d2b9ed040a9171364020ecc6a2 (diff) |
[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>
Diffstat (limited to 'include/scsi')
-rw-r--r-- | include/scsi/scsi_host.h | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index d3b1e06fb142..44a55d1bf530 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -636,6 +636,10 @@ struct Scsi_Host { | |||
636 | */ | 636 | */ |
637 | unsigned int max_host_blocked; | 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 | * q used for scsi_tgt msgs, async events or any other requests that | 644 | * q used for scsi_tgt msgs, async events or any other requests that |
641 | * need to be processed in userspace | 645 | * need to be processed in userspace |
@@ -756,6 +760,86 @@ extern struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, | |||
756 | extern void scsi_free_host_dev(struct scsi_device *); | 760 | extern void scsi_free_host_dev(struct scsi_device *); |
757 | extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *); | 761 | extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *); |
758 | 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 | } | ||
842 | |||
759 | /* legacy interfaces */ | 843 | /* legacy interfaces */ |
760 | extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); | 844 | extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); |
761 | extern void scsi_unregister(struct Scsi_Host *); | 845 | extern void scsi_unregister(struct Scsi_Host *); |