aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2013-12-23 15:30:03 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2014-01-18 04:53:11 -0500
commit499bf77b0169605a23c38351e3849066fe696877 (patch)
treefbe3e65676dd452c29bf1ac82ba97479579a5a32 /drivers/target
parentfcc4f17b9ce931c93ce08f8cf27d6bd010f0b1ef (diff)
target/sbc: Add DIF setup in sbc_check_prot + sbc_parse_cdb
This patch adds sbc_check_prot() for performing various DIF related CDB sanity checks, along with setting cmd->prot_type once sanity checks have passed. Also, add calls in sbc_parse_cdb() for READ_[10,12,16] + WRITE_[10,12,16] to perform DIF sanity checking. v2 changes: - Make sbc_check_prot defined as static (Fengguang + Wei) - Remove unprotected READ/WRITE warning (mkp) - Populate cmd->prot_type + friends (Sagi) - Drop SCF_PROT usage Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Hannes Reinecke <hare@suse.de> Cc: Sagi Grimberg <sagig@mellanox.com> Cc: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_sbc.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 6863dbe0aadf..91a92f354e9f 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -563,6 +563,44 @@ sbc_compare_and_write(struct se_cmd *cmd)
563 return TCM_NO_SENSE; 563 return TCM_NO_SENSE;
564} 564}
565 565
566static bool
567sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
568 u32 sectors)
569{
570 if (!cmd->t_prot_sg || !cmd->t_prot_nents)
571 return true;
572
573 switch (dev->dev_attrib.pi_prot_type) {
574 case TARGET_DIF_TYPE3_PROT:
575 if (!(cdb[1] & 0xe0))
576 return true;
577
578 cmd->reftag_seed = 0xffffffff;
579 break;
580 case TARGET_DIF_TYPE2_PROT:
581 if (cdb[1] & 0xe0)
582 return false;
583
584 cmd->reftag_seed = cmd->t_task_lba;
585 break;
586 case TARGET_DIF_TYPE1_PROT:
587 if (!(cdb[1] & 0xe0))
588 return true;
589
590 cmd->reftag_seed = cmd->t_task_lba;
591 break;
592 case TARGET_DIF_TYPE0_PROT:
593 default:
594 return true;
595 }
596
597 cmd->prot_type = dev->dev_attrib.pi_prot_type;
598 cmd->prot_length = dev->prot_length * sectors;
599 cmd->prot_handover = PROT_SEPERATED;
600
601 return true;
602}
603
566sense_reason_t 604sense_reason_t
567sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) 605sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
568{ 606{
@@ -583,6 +621,10 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
583 case READ_10: 621 case READ_10:
584 sectors = transport_get_sectors_10(cdb); 622 sectors = transport_get_sectors_10(cdb);
585 cmd->t_task_lba = transport_lba_32(cdb); 623 cmd->t_task_lba = transport_lba_32(cdb);
624
625 if (!sbc_check_prot(dev, cmd, cdb, sectors))
626 return TCM_UNSUPPORTED_SCSI_OPCODE;
627
586 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 628 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
587 cmd->execute_rw = ops->execute_rw; 629 cmd->execute_rw = ops->execute_rw;
588 cmd->execute_cmd = sbc_execute_rw; 630 cmd->execute_cmd = sbc_execute_rw;
@@ -590,6 +632,10 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
590 case READ_12: 632 case READ_12:
591 sectors = transport_get_sectors_12(cdb); 633 sectors = transport_get_sectors_12(cdb);
592 cmd->t_task_lba = transport_lba_32(cdb); 634 cmd->t_task_lba = transport_lba_32(cdb);
635
636 if (!sbc_check_prot(dev, cmd, cdb, sectors))
637 return TCM_UNSUPPORTED_SCSI_OPCODE;
638
593 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 639 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
594 cmd->execute_rw = ops->execute_rw; 640 cmd->execute_rw = ops->execute_rw;
595 cmd->execute_cmd = sbc_execute_rw; 641 cmd->execute_cmd = sbc_execute_rw;
@@ -597,6 +643,10 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
597 case READ_16: 643 case READ_16:
598 sectors = transport_get_sectors_16(cdb); 644 sectors = transport_get_sectors_16(cdb);
599 cmd->t_task_lba = transport_lba_64(cdb); 645 cmd->t_task_lba = transport_lba_64(cdb);
646
647 if (!sbc_check_prot(dev, cmd, cdb, sectors))
648 return TCM_UNSUPPORTED_SCSI_OPCODE;
649
600 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 650 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
601 cmd->execute_rw = ops->execute_rw; 651 cmd->execute_rw = ops->execute_rw;
602 cmd->execute_cmd = sbc_execute_rw; 652 cmd->execute_cmd = sbc_execute_rw;
@@ -612,6 +662,10 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
612 case WRITE_VERIFY: 662 case WRITE_VERIFY:
613 sectors = transport_get_sectors_10(cdb); 663 sectors = transport_get_sectors_10(cdb);
614 cmd->t_task_lba = transport_lba_32(cdb); 664 cmd->t_task_lba = transport_lba_32(cdb);
665
666 if (!sbc_check_prot(dev, cmd, cdb, sectors))
667 return TCM_UNSUPPORTED_SCSI_OPCODE;
668
615 if (cdb[1] & 0x8) 669 if (cdb[1] & 0x8)
616 cmd->se_cmd_flags |= SCF_FUA; 670 cmd->se_cmd_flags |= SCF_FUA;
617 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 671 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
@@ -621,6 +675,10 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
621 case WRITE_12: 675 case WRITE_12:
622 sectors = transport_get_sectors_12(cdb); 676 sectors = transport_get_sectors_12(cdb);
623 cmd->t_task_lba = transport_lba_32(cdb); 677 cmd->t_task_lba = transport_lba_32(cdb);
678
679 if (!sbc_check_prot(dev, cmd, cdb, sectors))
680 return TCM_UNSUPPORTED_SCSI_OPCODE;
681
624 if (cdb[1] & 0x8) 682 if (cdb[1] & 0x8)
625 cmd->se_cmd_flags |= SCF_FUA; 683 cmd->se_cmd_flags |= SCF_FUA;
626 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 684 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
@@ -630,6 +688,10 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
630 case WRITE_16: 688 case WRITE_16:
631 sectors = transport_get_sectors_16(cdb); 689 sectors = transport_get_sectors_16(cdb);
632 cmd->t_task_lba = transport_lba_64(cdb); 690 cmd->t_task_lba = transport_lba_64(cdb);
691
692 if (!sbc_check_prot(dev, cmd, cdb, sectors))
693 return TCM_UNSUPPORTED_SCSI_OPCODE;
694
633 if (cdb[1] & 0x8) 695 if (cdb[1] & 0x8)
634 cmd->se_cmd_flags |= SCF_FUA; 696 cmd->se_cmd_flags |= SCF_FUA;
635 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 697 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;