diff options
Diffstat (limited to 'drivers/target/target_core_user.c')
-rw-r--r-- | drivers/target/target_core_user.c | 143 |
1 files changed, 32 insertions, 111 deletions
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index dbc872a6c981..07d2996d8c1f 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c | |||
@@ -71,13 +71,6 @@ struct tcmu_hba { | |||
71 | u32 host_id; | 71 | u32 host_id; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | /* User wants all cmds or just some */ | ||
75 | enum passthru_level { | ||
76 | TCMU_PASS_ALL = 0, | ||
77 | TCMU_PASS_IO, | ||
78 | TCMU_PASS_INVALID, | ||
79 | }; | ||
80 | |||
81 | #define TCMU_CONFIG_LEN 256 | 74 | #define TCMU_CONFIG_LEN 256 |
82 | 75 | ||
83 | struct tcmu_dev { | 76 | struct tcmu_dev { |
@@ -89,7 +82,6 @@ struct tcmu_dev { | |||
89 | #define TCMU_DEV_BIT_OPEN 0 | 82 | #define TCMU_DEV_BIT_OPEN 0 |
90 | #define TCMU_DEV_BIT_BROKEN 1 | 83 | #define TCMU_DEV_BIT_BROKEN 1 |
91 | unsigned long flags; | 84 | unsigned long flags; |
92 | enum passthru_level pass_level; | ||
93 | 85 | ||
94 | struct uio_info uio_info; | 86 | struct uio_info uio_info; |
95 | 87 | ||
@@ -683,8 +675,6 @@ static struct se_device *tcmu_alloc_device(struct se_hba *hba, const char *name) | |||
683 | setup_timer(&udev->timeout, tcmu_device_timedout, | 675 | setup_timer(&udev->timeout, tcmu_device_timedout, |
684 | (unsigned long)udev); | 676 | (unsigned long)udev); |
685 | 677 | ||
686 | udev->pass_level = TCMU_PASS_ALL; | ||
687 | |||
688 | return &udev->se_dev; | 678 | return &udev->se_dev; |
689 | } | 679 | } |
690 | 680 | ||
@@ -948,13 +938,13 @@ static void tcmu_free_device(struct se_device *dev) | |||
948 | } | 938 | } |
949 | 939 | ||
950 | enum { | 940 | enum { |
951 | Opt_dev_config, Opt_dev_size, Opt_err, Opt_pass_level, | 941 | Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_err, |
952 | }; | 942 | }; |
953 | 943 | ||
954 | static match_table_t tokens = { | 944 | static match_table_t tokens = { |
955 | {Opt_dev_config, "dev_config=%s"}, | 945 | {Opt_dev_config, "dev_config=%s"}, |
956 | {Opt_dev_size, "dev_size=%u"}, | 946 | {Opt_dev_size, "dev_size=%u"}, |
957 | {Opt_pass_level, "pass_level=%u"}, | 947 | {Opt_hw_block_size, "hw_block_size=%u"}, |
958 | {Opt_err, NULL} | 948 | {Opt_err, NULL} |
959 | }; | 949 | }; |
960 | 950 | ||
@@ -965,7 +955,7 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, | |||
965 | char *orig, *ptr, *opts, *arg_p; | 955 | char *orig, *ptr, *opts, *arg_p; |
966 | substring_t args[MAX_OPT_ARGS]; | 956 | substring_t args[MAX_OPT_ARGS]; |
967 | int ret = 0, token; | 957 | int ret = 0, token; |
968 | int arg; | 958 | unsigned long tmp_ul; |
969 | 959 | ||
970 | opts = kstrdup(page, GFP_KERNEL); | 960 | opts = kstrdup(page, GFP_KERNEL); |
971 | if (!opts) | 961 | if (!opts) |
@@ -998,15 +988,23 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, | |||
998 | if (ret < 0) | 988 | if (ret < 0) |
999 | pr_err("kstrtoul() failed for dev_size=\n"); | 989 | pr_err("kstrtoul() failed for dev_size=\n"); |
1000 | break; | 990 | break; |
1001 | case Opt_pass_level: | 991 | case Opt_hw_block_size: |
1002 | match_int(args, &arg); | 992 | arg_p = match_strdup(&args[0]); |
1003 | if (arg >= TCMU_PASS_INVALID) { | 993 | if (!arg_p) { |
1004 | pr_warn("TCMU: Invalid pass_level: %d\n", arg); | 994 | ret = -ENOMEM; |
1005 | break; | 995 | break; |
1006 | } | 996 | } |
1007 | 997 | ret = kstrtoul(arg_p, 0, &tmp_ul); | |
1008 | pr_debug("TCMU: Setting pass_level to %d\n", arg); | 998 | kfree(arg_p); |
1009 | udev->pass_level = arg; | 999 | if (ret < 0) { |
1000 | pr_err("kstrtoul() failed for hw_block_size=\n"); | ||
1001 | break; | ||
1002 | } | ||
1003 | if (!tmp_ul) { | ||
1004 | pr_err("hw_block_size must be nonzero\n"); | ||
1005 | break; | ||
1006 | } | ||
1007 | dev->dev_attrib.hw_block_size = tmp_ul; | ||
1010 | break; | 1008 | break; |
1011 | default: | 1009 | default: |
1012 | break; | 1010 | break; |
@@ -1024,8 +1022,7 @@ static ssize_t tcmu_show_configfs_dev_params(struct se_device *dev, char *b) | |||
1024 | 1022 | ||
1025 | bl = sprintf(b + bl, "Config: %s ", | 1023 | bl = sprintf(b + bl, "Config: %s ", |
1026 | udev->dev_config[0] ? udev->dev_config : "NULL"); | 1024 | udev->dev_config[0] ? udev->dev_config : "NULL"); |
1027 | bl += sprintf(b + bl, "Size: %zu PassLevel: %u\n", | 1025 | bl += sprintf(b + bl, "Size: %zu\n", udev->dev_size); |
1028 | udev->dev_size, udev->pass_level); | ||
1029 | 1026 | ||
1030 | return bl; | 1027 | return bl; |
1031 | } | 1028 | } |
@@ -1039,20 +1036,6 @@ static sector_t tcmu_get_blocks(struct se_device *dev) | |||
1039 | } | 1036 | } |
1040 | 1037 | ||
1041 | static sense_reason_t | 1038 | static sense_reason_t |
1042 | tcmu_execute_rw(struct se_cmd *se_cmd, struct scatterlist *sgl, u32 sgl_nents, | ||
1043 | enum dma_data_direction data_direction) | ||
1044 | { | ||
1045 | int ret; | ||
1046 | |||
1047 | ret = tcmu_queue_cmd(se_cmd); | ||
1048 | |||
1049 | if (ret != 0) | ||
1050 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1051 | else | ||
1052 | return TCM_NO_SENSE; | ||
1053 | } | ||
1054 | |||
1055 | static sense_reason_t | ||
1056 | tcmu_pass_op(struct se_cmd *se_cmd) | 1039 | tcmu_pass_op(struct se_cmd *se_cmd) |
1057 | { | 1040 | { |
1058 | int ret = tcmu_queue_cmd(se_cmd); | 1041 | int ret = tcmu_queue_cmd(se_cmd); |
@@ -1063,91 +1046,29 @@ tcmu_pass_op(struct se_cmd *se_cmd) | |||
1063 | return TCM_NO_SENSE; | 1046 | return TCM_NO_SENSE; |
1064 | } | 1047 | } |
1065 | 1048 | ||
1066 | static struct sbc_ops tcmu_sbc_ops = { | ||
1067 | .execute_rw = tcmu_execute_rw, | ||
1068 | .execute_sync_cache = tcmu_pass_op, | ||
1069 | .execute_write_same = tcmu_pass_op, | ||
1070 | .execute_write_same_unmap = tcmu_pass_op, | ||
1071 | .execute_unmap = tcmu_pass_op, | ||
1072 | }; | ||
1073 | |||
1074 | static sense_reason_t | 1049 | static sense_reason_t |
1075 | tcmu_parse_cdb(struct se_cmd *cmd) | 1050 | tcmu_parse_cdb(struct se_cmd *cmd) |
1076 | { | 1051 | { |
1077 | unsigned char *cdb = cmd->t_task_cdb; | 1052 | return passthrough_parse_cdb(cmd, tcmu_pass_op); |
1078 | struct tcmu_dev *udev = TCMU_DEV(cmd->se_dev); | ||
1079 | sense_reason_t ret; | ||
1080 | |||
1081 | switch (udev->pass_level) { | ||
1082 | case TCMU_PASS_ALL: | ||
1083 | /* We're just like pscsi, then */ | ||
1084 | /* | ||
1085 | * For REPORT LUNS we always need to emulate the response, for everything | ||
1086 | * else, pass it up. | ||
1087 | */ | ||
1088 | switch (cdb[0]) { | ||
1089 | case REPORT_LUNS: | ||
1090 | cmd->execute_cmd = spc_emulate_report_luns; | ||
1091 | break; | ||
1092 | case READ_6: | ||
1093 | case READ_10: | ||
1094 | case READ_12: | ||
1095 | case READ_16: | ||
1096 | case WRITE_6: | ||
1097 | case WRITE_10: | ||
1098 | case WRITE_12: | ||
1099 | case WRITE_16: | ||
1100 | case WRITE_VERIFY: | ||
1101 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; | ||
1102 | /* FALLTHROUGH */ | ||
1103 | default: | ||
1104 | cmd->execute_cmd = tcmu_pass_op; | ||
1105 | } | ||
1106 | ret = TCM_NO_SENSE; | ||
1107 | break; | ||
1108 | case TCMU_PASS_IO: | ||
1109 | ret = sbc_parse_cdb(cmd, &tcmu_sbc_ops); | ||
1110 | break; | ||
1111 | default: | ||
1112 | pr_err("Unknown tcm-user pass level %d\n", udev->pass_level); | ||
1113 | ret = TCM_CHECK_CONDITION_ABORT_CMD; | ||
1114 | } | ||
1115 | |||
1116 | return ret; | ||
1117 | } | 1053 | } |
1118 | 1054 | ||
1119 | DEF_TB_DEFAULT_ATTRIBS(tcmu); | 1055 | DEF_TB_DEV_ATTRIB_RO(tcmu, hw_pi_prot_type); |
1056 | TB_DEV_ATTR_RO(tcmu, hw_pi_prot_type); | ||
1057 | |||
1058 | DEF_TB_DEV_ATTRIB_RO(tcmu, hw_block_size); | ||
1059 | TB_DEV_ATTR_RO(tcmu, hw_block_size); | ||
1060 | |||
1061 | DEF_TB_DEV_ATTRIB_RO(tcmu, hw_max_sectors); | ||
1062 | TB_DEV_ATTR_RO(tcmu, hw_max_sectors); | ||
1063 | |||
1064 | DEF_TB_DEV_ATTRIB_RO(tcmu, hw_queue_depth); | ||
1065 | TB_DEV_ATTR_RO(tcmu, hw_queue_depth); | ||
1120 | 1066 | ||
1121 | static struct configfs_attribute *tcmu_backend_dev_attrs[] = { | 1067 | static struct configfs_attribute *tcmu_backend_dev_attrs[] = { |
1122 | &tcmu_dev_attrib_emulate_model_alias.attr, | ||
1123 | &tcmu_dev_attrib_emulate_dpo.attr, | ||
1124 | &tcmu_dev_attrib_emulate_fua_write.attr, | ||
1125 | &tcmu_dev_attrib_emulate_fua_read.attr, | ||
1126 | &tcmu_dev_attrib_emulate_write_cache.attr, | ||
1127 | &tcmu_dev_attrib_emulate_ua_intlck_ctrl.attr, | ||
1128 | &tcmu_dev_attrib_emulate_tas.attr, | ||
1129 | &tcmu_dev_attrib_emulate_tpu.attr, | ||
1130 | &tcmu_dev_attrib_emulate_tpws.attr, | ||
1131 | &tcmu_dev_attrib_emulate_caw.attr, | ||
1132 | &tcmu_dev_attrib_emulate_3pc.attr, | ||
1133 | &tcmu_dev_attrib_pi_prot_type.attr, | ||
1134 | &tcmu_dev_attrib_hw_pi_prot_type.attr, | 1068 | &tcmu_dev_attrib_hw_pi_prot_type.attr, |
1135 | &tcmu_dev_attrib_pi_prot_format.attr, | ||
1136 | &tcmu_dev_attrib_enforce_pr_isids.attr, | ||
1137 | &tcmu_dev_attrib_is_nonrot.attr, | ||
1138 | &tcmu_dev_attrib_emulate_rest_reord.attr, | ||
1139 | &tcmu_dev_attrib_force_pr_aptpl.attr, | ||
1140 | &tcmu_dev_attrib_hw_block_size.attr, | 1069 | &tcmu_dev_attrib_hw_block_size.attr, |
1141 | &tcmu_dev_attrib_block_size.attr, | ||
1142 | &tcmu_dev_attrib_hw_max_sectors.attr, | 1070 | &tcmu_dev_attrib_hw_max_sectors.attr, |
1143 | &tcmu_dev_attrib_optimal_sectors.attr, | ||
1144 | &tcmu_dev_attrib_hw_queue_depth.attr, | 1071 | &tcmu_dev_attrib_hw_queue_depth.attr, |
1145 | &tcmu_dev_attrib_queue_depth.attr, | ||
1146 | &tcmu_dev_attrib_max_unmap_lba_count.attr, | ||
1147 | &tcmu_dev_attrib_max_unmap_block_desc_count.attr, | ||
1148 | &tcmu_dev_attrib_unmap_granularity.attr, | ||
1149 | &tcmu_dev_attrib_unmap_granularity_alignment.attr, | ||
1150 | &tcmu_dev_attrib_max_write_same_len.attr, | ||
1151 | NULL, | 1072 | NULL, |
1152 | }; | 1073 | }; |
1153 | 1074 | ||
@@ -1156,7 +1077,7 @@ static struct se_subsystem_api tcmu_template = { | |||
1156 | .inquiry_prod = "USER", | 1077 | .inquiry_prod = "USER", |
1157 | .inquiry_rev = TCMU_VERSION, | 1078 | .inquiry_rev = TCMU_VERSION, |
1158 | .owner = THIS_MODULE, | 1079 | .owner = THIS_MODULE, |
1159 | .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, | 1080 | .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, |
1160 | .attach_hba = tcmu_attach_hba, | 1081 | .attach_hba = tcmu_attach_hba, |
1161 | .detach_hba = tcmu_detach_hba, | 1082 | .detach_hba = tcmu_detach_hba, |
1162 | .alloc_device = tcmu_alloc_device, | 1083 | .alloc_device = tcmu_alloc_device, |