aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2012-10-07 10:55:51 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-11-06 23:55:44 -0500
commitd1b1f8053401aaf1dfe636afa6d361301e3ae8b7 (patch)
tree52a04af8a2383ce291105b4b5d01bb869802f33c
parent9e999a6c51fe74a41a76038c64ce038ff9243bfb (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.c63
-rw-r--r--drivers/target/target_core_internal.h1
-rw-r--r--drivers/target/target_core_spc.c65
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
649int 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 */
700done:
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
712static void se_release_vpd_for_dev(struct se_device *dev) 649static 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 *);
20void core_dev_unexport(struct se_device *, struct se_portal_group *, 20void core_dev_unexport(struct se_device *, struct se_portal_group *,
21 struct se_lun *); 21 struct se_lun *);
22int target_report_luns(struct se_cmd *);
23int se_dev_set_task_timeout(struct se_device *, u32); 22int se_dev_set_task_timeout(struct se_device *, u32);
24int se_dev_set_max_unmap_lba_count(struct se_device *, u32); 23int se_dev_set_max_unmap_lba_count(struct se_device *, u32);
25int se_dev_set_max_unmap_block_desc_count(struct se_device *, u32); 24int 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
911static 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 */
962done:
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
911static int spc_emulate_testunitready(struct se_cmd *cmd) 974static 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