aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2008-07-17 04:28:30 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-07-26 15:14:54 -0400
commit4469f9878059f1707f021512e6b34252c4096ee7 (patch)
tree3bc8ea358bea85235a8d9691c8b999626e685e0d
parent7c32c7a2d36c52d2b9ed040a9171364020ecc6a2 (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>
-rw-r--r--drivers/scsi/scsi_sysfs.c4
-rw-r--r--include/scsi/scsi_host.h84
2 files changed, 88 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index b6e561059779..ab3c71869be5 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -249,6 +249,8 @@ shost_rd_attr(cmd_per_lun, "%hd\n");
249shost_rd_attr(can_queue, "%hd\n"); 249shost_rd_attr(can_queue, "%hd\n");
250shost_rd_attr(sg_tablesize, "%hu\n"); 250shost_rd_attr(sg_tablesize, "%hu\n");
251shost_rd_attr(unchecked_isa_dma, "%d\n"); 251shost_rd_attr(unchecked_isa_dma, "%d\n");
252shost_rd_attr(prot_capabilities, "%u\n");
253shost_rd_attr(prot_guard_type, "%hd\n");
252shost_rd_attr2(proc_name, hostt->proc_name, "%s\n"); 254shost_rd_attr2(proc_name, hostt->proc_name, "%s\n");
253 255
254static struct attribute *scsi_sysfs_shost_attrs[] = { 256static struct attribute *scsi_sysfs_shost_attrs[] = {
@@ -263,6 +265,8 @@ static struct attribute *scsi_sysfs_shost_attrs[] = {
263 &dev_attr_hstate.attr, 265 &dev_attr_hstate.attr,
264 &dev_attr_supported_mode.attr, 266 &dev_attr_supported_mode.attr,
265 &dev_attr_active_mode.attr, 267 &dev_attr_active_mode.attr,
268 &dev_attr_prot_capabilities.attr,
269 &dev_attr_prot_guard_type.attr,
266 NULL 270 NULL
267}; 271};
268 272
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,
756extern void scsi_free_host_dev(struct scsi_device *); 760extern void scsi_free_host_dev(struct scsi_device *);
757extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *); 761extern 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 */
770enum 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 */
786static inline void scsi_host_set_prot(struct Scsi_Host *shost, unsigned int mask)
787{
788 shost->prot_capabilities = mask;
789}
790
791static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost)
792{
793 return shost->prot_capabilities;
794}
795
796static 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
807static 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
828enum scsi_host_guard_type {
829 SHOST_DIX_GUARD_CRC = 1 << 0,
830 SHOST_DIX_GUARD_IP = 1 << 1,
831};
832
833static inline void scsi_host_set_guard(struct Scsi_Host *shost, unsigned char type)
834{
835 shost->prot_guard_type = type;
836}
837
838static 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 */
760extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); 844extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int);
761extern void scsi_unregister(struct Scsi_Host *); 845extern void scsi_unregister(struct Scsi_Host *);