Commit 4469f9878059f1707f021512e6b34252c4096ee7

Authored by Martin K. Petersen
Committed by James Bottomley
1 parent 7c32c7a2d3

[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);