diff options
author | Christoph Hellwig <hch@infradead.org> | 2012-10-07 10:55:51 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-11-06 23:55:44 -0500 |
commit | d1b1f8053401aaf1dfe636afa6d361301e3ae8b7 (patch) | |
tree | 52a04af8a2383ce291105b4b5d01bb869802f33c | |
parent | 9e999a6c51fe74a41a76038c64ce038ff9243bfb (diff) |
target: move REPORT LUNS emulation to target_core_spc.c
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/target_core_device.c | 63 | ||||
-rw-r--r-- | drivers/target/target_core_internal.h | 1 | ||||
-rw-r--r-- | drivers/target/target_core_spc.c | 65 |
3 files changed, 64 insertions, 65 deletions
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index b27c75a0e2e2..e45a70970548 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -646,69 +646,6 @@ void core_dev_unexport( | |||
646 | lun->lun_se_dev = NULL; | 646 | lun->lun_se_dev = NULL; |
647 | } | 647 | } |
648 | 648 | ||
649 | int target_report_luns(struct se_cmd *se_cmd) | ||
650 | { | ||
651 | struct se_dev_entry *deve; | ||
652 | struct se_session *se_sess = se_cmd->se_sess; | ||
653 | unsigned char *buf; | ||
654 | u32 lun_count = 0, offset = 8, i; | ||
655 | |||
656 | if (se_cmd->data_length < 16) { | ||
657 | pr_warn("REPORT LUNS allocation length %u too small\n", | ||
658 | se_cmd->data_length); | ||
659 | se_cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
660 | return -EINVAL; | ||
661 | } | ||
662 | |||
663 | buf = transport_kmap_data_sg(se_cmd); | ||
664 | if (!buf) | ||
665 | return -ENOMEM; | ||
666 | |||
667 | /* | ||
668 | * If no struct se_session pointer is present, this struct se_cmd is | ||
669 | * coming via a target_core_mod PASSTHROUGH op, and not through | ||
670 | * a $FABRIC_MOD. In that case, report LUN=0 only. | ||
671 | */ | ||
672 | if (!se_sess) { | ||
673 | int_to_scsilun(0, (struct scsi_lun *)&buf[offset]); | ||
674 | lun_count = 1; | ||
675 | goto done; | ||
676 | } | ||
677 | |||
678 | spin_lock_irq(&se_sess->se_node_acl->device_list_lock); | ||
679 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { | ||
680 | deve = se_sess->se_node_acl->device_list[i]; | ||
681 | if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) | ||
682 | continue; | ||
683 | /* | ||
684 | * We determine the correct LUN LIST LENGTH even once we | ||
685 | * have reached the initial allocation length. | ||
686 | * See SPC2-R20 7.19. | ||
687 | */ | ||
688 | lun_count++; | ||
689 | if ((offset + 8) > se_cmd->data_length) | ||
690 | continue; | ||
691 | |||
692 | int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]); | ||
693 | offset += 8; | ||
694 | } | ||
695 | spin_unlock_irq(&se_sess->se_node_acl->device_list_lock); | ||
696 | |||
697 | /* | ||
698 | * See SPC3 r07, page 159. | ||
699 | */ | ||
700 | done: | ||
701 | lun_count *= 8; | ||
702 | buf[0] = ((lun_count >> 24) & 0xff); | ||
703 | buf[1] = ((lun_count >> 16) & 0xff); | ||
704 | buf[2] = ((lun_count >> 8) & 0xff); | ||
705 | buf[3] = (lun_count & 0xff); | ||
706 | transport_kunmap_data_sg(se_cmd); | ||
707 | |||
708 | target_complete_cmd(se_cmd, GOOD); | ||
709 | return 0; | ||
710 | } | ||
711 | |||
712 | static void se_release_vpd_for_dev(struct se_device *dev) | 649 | static void se_release_vpd_for_dev(struct se_device *dev) |
713 | { | 650 | { |
714 | struct t10_vpd *vpd, *vpd_tmp; | 651 | struct t10_vpd *vpd, *vpd_tmp; |
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 5854ed67af59..2f37720c4db3 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h | |||
@@ -19,7 +19,6 @@ int core_dev_export(struct se_device *, struct se_portal_group *, | |||
19 | struct se_lun *); | 19 | struct se_lun *); |
20 | void core_dev_unexport(struct se_device *, struct se_portal_group *, | 20 | void core_dev_unexport(struct se_device *, struct se_portal_group *, |
21 | struct se_lun *); | 21 | struct se_lun *); |
22 | int target_report_luns(struct se_cmd *); | ||
23 | int se_dev_set_task_timeout(struct se_device *, u32); | 22 | int se_dev_set_task_timeout(struct se_device *, u32); |
24 | int se_dev_set_max_unmap_lba_count(struct se_device *, u32); | 23 | int se_dev_set_max_unmap_lba_count(struct se_device *, u32); |
25 | int se_dev_set_max_unmap_block_desc_count(struct se_device *, u32); | 24 | int se_dev_set_max_unmap_block_desc_count(struct se_device *, u32); |
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 0af45ae32f8c..07b82700dcd8 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -908,6 +908,69 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
908 | return 0; | 908 | return 0; |
909 | } | 909 | } |
910 | 910 | ||
911 | static int spc_emulate_report_luns(struct se_cmd *cmd) | ||
912 | { | ||
913 | struct se_dev_entry *deve; | ||
914 | struct se_session *sess = cmd->se_sess; | ||
915 | unsigned char *buf; | ||
916 | u32 lun_count = 0, offset = 8, i; | ||
917 | |||
918 | if (cmd->data_length < 16) { | ||
919 | pr_warn("REPORT LUNS allocation length %u too small\n", | ||
920 | cmd->data_length); | ||
921 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
922 | return -EINVAL; | ||
923 | } | ||
924 | |||
925 | buf = transport_kmap_data_sg(cmd); | ||
926 | if (!buf) | ||
927 | return -ENOMEM; | ||
928 | |||
929 | /* | ||
930 | * If no struct se_session pointer is present, this struct se_cmd is | ||
931 | * coming via a target_core_mod PASSTHROUGH op, and not through | ||
932 | * a $FABRIC_MOD. In that case, report LUN=0 only. | ||
933 | */ | ||
934 | if (!sess) { | ||
935 | int_to_scsilun(0, (struct scsi_lun *)&buf[offset]); | ||
936 | lun_count = 1; | ||
937 | goto done; | ||
938 | } | ||
939 | |||
940 | spin_lock_irq(&sess->se_node_acl->device_list_lock); | ||
941 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { | ||
942 | deve = sess->se_node_acl->device_list[i]; | ||
943 | if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) | ||
944 | continue; | ||
945 | /* | ||
946 | * We determine the correct LUN LIST LENGTH even once we | ||
947 | * have reached the initial allocation length. | ||
948 | * See SPC2-R20 7.19. | ||
949 | */ | ||
950 | lun_count++; | ||
951 | if ((offset + 8) > cmd->data_length) | ||
952 | continue; | ||
953 | |||
954 | int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]); | ||
955 | offset += 8; | ||
956 | } | ||
957 | spin_unlock_irq(&sess->se_node_acl->device_list_lock); | ||
958 | |||
959 | /* | ||
960 | * See SPC3 r07, page 159. | ||
961 | */ | ||
962 | done: | ||
963 | lun_count *= 8; | ||
964 | buf[0] = ((lun_count >> 24) & 0xff); | ||
965 | buf[1] = ((lun_count >> 16) & 0xff); | ||
966 | buf[2] = ((lun_count >> 8) & 0xff); | ||
967 | buf[3] = (lun_count & 0xff); | ||
968 | transport_kunmap_data_sg(cmd); | ||
969 | |||
970 | target_complete_cmd(cmd, GOOD); | ||
971 | return 0; | ||
972 | } | ||
973 | |||
911 | static int spc_emulate_testunitready(struct se_cmd *cmd) | 974 | static int spc_emulate_testunitready(struct se_cmd *cmd) |
912 | { | 975 | { |
913 | target_complete_cmd(cmd, GOOD); | 976 | target_complete_cmd(cmd, GOOD); |
@@ -1013,7 +1076,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
1013 | *size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; | 1076 | *size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; |
1014 | break; | 1077 | break; |
1015 | case REPORT_LUNS: | 1078 | case REPORT_LUNS: |
1016 | cmd->execute_cmd = target_report_luns; | 1079 | cmd->execute_cmd = spc_emulate_report_luns; |
1017 | *size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; | 1080 | *size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; |
1018 | /* | 1081 | /* |
1019 | * Do implict HEAD_OF_QUEUE processing for REPORT_LUNS | 1082 | * Do implict HEAD_OF_QUEUE processing for REPORT_LUNS |