aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorSagi Grimberg <sagig@mellanox.com>2014-02-19 10:50:15 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2014-03-13 15:03:02 -0400
commit19f9361af7dfa0bb1f98c7619544ed71d2dded39 (patch)
tree4afa7db32e56d65500661134906c729699f226bc /drivers/target
parentacb2bde3e32100f1ab50e38f0db03660a1cb0a06 (diff)
Target/sbc: Set protection operation and relevant checks
SBC-3 mandates the protection checks that must be performed in the rdprotect/wrprotect field. Use them. According to backstore device pi_attributes and cdb rdprotect/wrprotect field. (Fix incorrect se_cmd->prot_type -> TARGET_PROT_NORMAL comparision in transport_generic_new_cmd - nab) (Fix missing break in sbc_set_prot_op_checks - DanC + Sagi) Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_sbc.c87
-rw-r--r--drivers/target/target_core_transport.c2
2 files changed, 74 insertions, 15 deletions
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 77e6531fb0a1..a1e75dd636ac 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -569,30 +569,85 @@ sbc_compare_and_write(struct se_cmd *cmd)
569 return TCM_NO_SENSE; 569 return TCM_NO_SENSE;
570} 570}
571 571
572static int
573sbc_set_prot_op_checks(u8 protect, enum target_prot_type prot_type,
574 bool is_write, struct se_cmd *cmd)
575{
576 if (is_write) {
577 cmd->prot_op = protect ? TARGET_PROT_DOUT_PASS :
578 TARGET_PROT_DOUT_INSERT;
579 switch (protect) {
580 case 0x0:
581 case 0x3:
582 cmd->prot_checks = 0;
583 break;
584 case 0x1:
585 case 0x5:
586 cmd->prot_checks = TARGET_DIF_CHECK_GUARD;
587 if (prot_type == TARGET_DIF_TYPE1_PROT)
588 cmd->prot_checks |= TARGET_DIF_CHECK_REFTAG;
589 break;
590 case 0x2:
591 if (prot_type == TARGET_DIF_TYPE1_PROT)
592 cmd->prot_checks = TARGET_DIF_CHECK_REFTAG;
593 break;
594 case 0x4:
595 cmd->prot_checks = TARGET_DIF_CHECK_GUARD;
596 break;
597 default:
598 pr_err("Unsupported protect field %d\n", protect);
599 return -EINVAL;
600 }
601 } else {
602 cmd->prot_op = protect ? TARGET_PROT_DIN_PASS :
603 TARGET_PROT_DIN_STRIP;
604 switch (protect) {
605 case 0x0:
606 case 0x1:
607 case 0x5:
608 cmd->prot_checks = TARGET_DIF_CHECK_GUARD;
609 if (prot_type == TARGET_DIF_TYPE1_PROT)
610 cmd->prot_checks |= TARGET_DIF_CHECK_REFTAG;
611 break;
612 case 0x2:
613 if (prot_type == TARGET_DIF_TYPE1_PROT)
614 cmd->prot_checks = TARGET_DIF_CHECK_REFTAG;
615 break;
616 case 0x3:
617 cmd->prot_checks = 0;
618 break;
619 case 0x4:
620 cmd->prot_checks = TARGET_DIF_CHECK_GUARD;
621 break;
622 default:
623 pr_err("Unsupported protect field %d\n", protect);
624 return -EINVAL;
625 }
626 }
627
628 return 0;
629}
630
572static bool 631static bool
573sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb, 632sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
574 u32 sectors) 633 u32 sectors, bool is_write)
575{ 634{
635 u8 protect = cdb[1] >> 5;
636
576 if (!cmd->t_prot_sg || !cmd->t_prot_nents) 637 if (!cmd->t_prot_sg || !cmd->t_prot_nents)
577 return true; 638 return true;
578 639
579 switch (dev->dev_attrib.pi_prot_type) { 640 switch (dev->dev_attrib.pi_prot_type) {
580 case TARGET_DIF_TYPE3_PROT: 641 case TARGET_DIF_TYPE3_PROT:
581 if (!(cdb[1] & 0xe0))
582 return true;
583
584 cmd->reftag_seed = 0xffffffff; 642 cmd->reftag_seed = 0xffffffff;
585 break; 643 break;
586 case TARGET_DIF_TYPE2_PROT: 644 case TARGET_DIF_TYPE2_PROT:
587 if (cdb[1] & 0xe0) 645 if (protect)
588 return false; 646 return false;
589 647
590 cmd->reftag_seed = cmd->t_task_lba; 648 cmd->reftag_seed = cmd->t_task_lba;
591 break; 649 break;
592 case TARGET_DIF_TYPE1_PROT: 650 case TARGET_DIF_TYPE1_PROT:
593 if (!(cdb[1] & 0xe0))
594 return true;
595
596 cmd->reftag_seed = cmd->t_task_lba; 651 cmd->reftag_seed = cmd->t_task_lba;
597 break; 652 break;
598 case TARGET_DIF_TYPE0_PROT: 653 case TARGET_DIF_TYPE0_PROT:
@@ -600,6 +655,10 @@ sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
600 return true; 655 return true;
601 } 656 }
602 657
658 if (sbc_set_prot_op_checks(protect, dev->dev_attrib.pi_prot_type,
659 is_write, cmd))
660 return false;
661
603 cmd->prot_type = dev->dev_attrib.pi_prot_type; 662 cmd->prot_type = dev->dev_attrib.pi_prot_type;
604 cmd->prot_length = dev->prot_length * sectors; 663 cmd->prot_length = dev->prot_length * sectors;
605 cmd->prot_handover = PROT_SEPERATED; 664 cmd->prot_handover = PROT_SEPERATED;
@@ -628,7 +687,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
628 sectors = transport_get_sectors_10(cdb); 687 sectors = transport_get_sectors_10(cdb);
629 cmd->t_task_lba = transport_lba_32(cdb); 688 cmd->t_task_lba = transport_lba_32(cdb);
630 689
631 if (!sbc_check_prot(dev, cmd, cdb, sectors)) 690 if (!sbc_check_prot(dev, cmd, cdb, sectors, false))
632 return TCM_UNSUPPORTED_SCSI_OPCODE; 691 return TCM_UNSUPPORTED_SCSI_OPCODE;
633 692
634 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 693 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
@@ -639,7 +698,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
639 sectors = transport_get_sectors_12(cdb); 698 sectors = transport_get_sectors_12(cdb);
640 cmd->t_task_lba = transport_lba_32(cdb); 699 cmd->t_task_lba = transport_lba_32(cdb);
641 700
642 if (!sbc_check_prot(dev, cmd, cdb, sectors)) 701 if (!sbc_check_prot(dev, cmd, cdb, sectors, false))
643 return TCM_UNSUPPORTED_SCSI_OPCODE; 702 return TCM_UNSUPPORTED_SCSI_OPCODE;
644 703
645 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 704 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
@@ -650,7 +709,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
650 sectors = transport_get_sectors_16(cdb); 709 sectors = transport_get_sectors_16(cdb);
651 cmd->t_task_lba = transport_lba_64(cdb); 710 cmd->t_task_lba = transport_lba_64(cdb);
652 711
653 if (!sbc_check_prot(dev, cmd, cdb, sectors)) 712 if (!sbc_check_prot(dev, cmd, cdb, sectors, false))
654 return TCM_UNSUPPORTED_SCSI_OPCODE; 713 return TCM_UNSUPPORTED_SCSI_OPCODE;
655 714
656 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 715 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
@@ -669,7 +728,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
669 sectors = transport_get_sectors_10(cdb); 728 sectors = transport_get_sectors_10(cdb);
670 cmd->t_task_lba = transport_lba_32(cdb); 729 cmd->t_task_lba = transport_lba_32(cdb);
671 730
672 if (!sbc_check_prot(dev, cmd, cdb, sectors)) 731 if (!sbc_check_prot(dev, cmd, cdb, sectors, true))
673 return TCM_UNSUPPORTED_SCSI_OPCODE; 732 return TCM_UNSUPPORTED_SCSI_OPCODE;
674 733
675 if (cdb[1] & 0x8) 734 if (cdb[1] & 0x8)
@@ -682,7 +741,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
682 sectors = transport_get_sectors_12(cdb); 741 sectors = transport_get_sectors_12(cdb);
683 cmd->t_task_lba = transport_lba_32(cdb); 742 cmd->t_task_lba = transport_lba_32(cdb);
684 743
685 if (!sbc_check_prot(dev, cmd, cdb, sectors)) 744 if (!sbc_check_prot(dev, cmd, cdb, sectors, true))
686 return TCM_UNSUPPORTED_SCSI_OPCODE; 745 return TCM_UNSUPPORTED_SCSI_OPCODE;
687 746
688 if (cdb[1] & 0x8) 747 if (cdb[1] & 0x8)
@@ -695,7 +754,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
695 sectors = transport_get_sectors_16(cdb); 754 sectors = transport_get_sectors_16(cdb);
696 cmd->t_task_lba = transport_lba_64(cdb); 755 cmd->t_task_lba = transport_lba_64(cdb);
697 756
698 if (!sbc_check_prot(dev, cmd, cdb, sectors)) 757 if (!sbc_check_prot(dev, cmd, cdb, sectors, true))
699 return TCM_UNSUPPORTED_SCSI_OPCODE; 758 return TCM_UNSUPPORTED_SCSI_OPCODE;
700 759
701 if (cdb[1] & 0x8) 760 if (cdb[1] & 0x8)
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 6ddd4cfc53ba..4653d826e595 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2206,7 +2206,7 @@ transport_generic_new_cmd(struct se_cmd *cmd)
2206 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 2206 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2207 } 2207 }
2208 2208
2209 if (cmd->prot_type != TARGET_PROT_NORMAL) { 2209 if (cmd->prot_op != TARGET_PROT_NORMAL) {
2210 ret = target_alloc_sgl(&cmd->t_prot_sg, 2210 ret = target_alloc_sgl(&cmd->t_prot_sg,
2211 &cmd->t_prot_nents, 2211 &cmd->t_prot_nents,
2212 cmd->prot_length, true); 2212 cmd->prot_length, true);