diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-12-23 15:30:03 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-01-18 04:53:11 -0500 |
commit | 499bf77b0169605a23c38351e3849066fe696877 (patch) | |
tree | fbe3e65676dd452c29bf1ac82ba97479579a5a32 /drivers/target | |
parent | fcc4f17b9ce931c93ce08f8cf27d6bd010f0b1ef (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.c | 62 |
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 | ||
566 | static bool | ||
567 | sbc_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 | |||
566 | sense_reason_t | 604 | sense_reason_t |
567 | sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | 605 | sbc_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; |