diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-11-03 17:50:45 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-11-04 06:44:35 -0400 |
commit | 5bda90c8f20f0af93375721533f4081a40fa6f41 (patch) | |
tree | 0ac0395e80359e8b4b8fc4220effc7a6225d259b /drivers/target | |
parent | d29a5b6acc4b63d4e05ff554509df6fbeaf527cd (diff) |
target: use ->exectute_task for all CDB emulation
Instead of calling into transport_emulate_control_cdb from
__transport_execute_tasks for some CDBs always set up ->exectute_tasks
in the command sequence and use it uniformly.
(nab: Add default passthrough break for SERVICE_ACTION_IN)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_cdb.c | 111 | ||||
-rw-r--r-- | drivers/target/target_core_cdb.h | 14 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 112 |
3 files changed, 97 insertions, 140 deletions
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 5a03085304e5..683ba02b8247 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <target/target_core_transport.h> | 32 | #include <target/target_core_transport.h> |
33 | #include <target/target_core_fabric_ops.h> | 33 | #include <target/target_core_fabric_ops.h> |
34 | #include "target_core_ua.h" | 34 | #include "target_core_ua.h" |
35 | #include "target_core_cdb.h" | ||
35 | 36 | ||
36 | static void | 37 | static void |
37 | target_fill_alua_data(struct se_port *port, unsigned char *buf) | 38 | target_fill_alua_data(struct se_port *port, unsigned char *buf) |
@@ -679,8 +680,7 @@ target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) | |||
679 | return 0; | 680 | return 0; |
680 | } | 681 | } |
681 | 682 | ||
682 | static int | 683 | int target_emulate_inquiry(struct se_task *task) |
683 | target_emulate_inquiry(struct se_task *task) | ||
684 | { | 684 | { |
685 | struct se_cmd *cmd = task->task_se_cmd; | 685 | struct se_cmd *cmd = task->task_se_cmd; |
686 | struct se_device *dev = cmd->se_dev; | 686 | struct se_device *dev = cmd->se_dev; |
@@ -731,8 +731,7 @@ out: | |||
731 | return ret; | 731 | return ret; |
732 | } | 732 | } |
733 | 733 | ||
734 | static int | 734 | int target_emulate_readcapacity(struct se_task *task) |
735 | target_emulate_readcapacity(struct se_task *task) | ||
736 | { | 735 | { |
737 | struct se_cmd *cmd = task->task_se_cmd; | 736 | struct se_cmd *cmd = task->task_se_cmd; |
738 | struct se_device *dev = cmd->se_dev; | 737 | struct se_device *dev = cmd->se_dev; |
@@ -768,8 +767,7 @@ target_emulate_readcapacity(struct se_task *task) | |||
768 | return 0; | 767 | return 0; |
769 | } | 768 | } |
770 | 769 | ||
771 | static int | 770 | int target_emulate_readcapacity_16(struct se_task *task) |
772 | target_emulate_readcapacity_16(struct se_task *task) | ||
773 | { | 771 | { |
774 | struct se_cmd *cmd = task->task_se_cmd; | 772 | struct se_cmd *cmd = task->task_se_cmd; |
775 | struct se_device *dev = cmd->se_dev; | 773 | struct se_device *dev = cmd->se_dev; |
@@ -939,8 +937,7 @@ target_modesense_dpofua(unsigned char *buf, int type) | |||
939 | } | 937 | } |
940 | } | 938 | } |
941 | 939 | ||
942 | static int | 940 | int target_emulate_modesense(struct se_task *task) |
943 | target_emulate_modesense(struct se_task *task) | ||
944 | { | 941 | { |
945 | struct se_cmd *cmd = task->task_se_cmd; | 942 | struct se_cmd *cmd = task->task_se_cmd; |
946 | struct se_device *dev = cmd->se_dev; | 943 | struct se_device *dev = cmd->se_dev; |
@@ -1019,8 +1016,7 @@ target_emulate_modesense(struct se_task *task) | |||
1019 | return 0; | 1016 | return 0; |
1020 | } | 1017 | } |
1021 | 1018 | ||
1022 | static int | 1019 | int target_emulate_request_sense(struct se_task *task) |
1023 | target_emulate_request_sense(struct se_task *task) | ||
1024 | { | 1020 | { |
1025 | struct se_cmd *cmd = task->task_se_cmd; | 1021 | struct se_cmd *cmd = task->task_se_cmd; |
1026 | unsigned char *cdb = cmd->t_task_cdb; | 1022 | unsigned char *cdb = cmd->t_task_cdb; |
@@ -1090,8 +1086,7 @@ end: | |||
1090 | * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support. | 1086 | * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support. |
1091 | * Note this is not used for TCM/pSCSI passthrough | 1087 | * Note this is not used for TCM/pSCSI passthrough |
1092 | */ | 1088 | */ |
1093 | static int | 1089 | int target_emulate_unmap(struct se_task *task) |
1094 | target_emulate_unmap(struct se_task *task) | ||
1095 | { | 1090 | { |
1096 | struct se_cmd *cmd = task->task_se_cmd; | 1091 | struct se_cmd *cmd = task->task_se_cmd; |
1097 | struct se_device *dev = cmd->se_dev; | 1092 | struct se_device *dev = cmd->se_dev; |
@@ -1150,8 +1145,7 @@ err: | |||
1150 | * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support. | 1145 | * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support. |
1151 | * Note this is not used for TCM/pSCSI passthrough | 1146 | * Note this is not used for TCM/pSCSI passthrough |
1152 | */ | 1147 | */ |
1153 | static int | 1148 | int target_emulate_write_same(struct se_task *task) |
1154 | target_emulate_write_same(struct se_task *task) | ||
1155 | { | 1149 | { |
1156 | struct se_cmd *cmd = task->task_se_cmd; | 1150 | struct se_cmd *cmd = task->task_se_cmd; |
1157 | struct se_device *dev = cmd->se_dev; | 1151 | struct se_device *dev = cmd->se_dev; |
@@ -1196,8 +1190,7 @@ target_emulate_write_same(struct se_task *task) | |||
1196 | return 0; | 1190 | return 0; |
1197 | } | 1191 | } |
1198 | 1192 | ||
1199 | static int | 1193 | int target_emulate_synchronize_cache(struct se_task *task) |
1200 | target_emulate_synchronize_cache(struct se_task *task) | ||
1201 | { | 1194 | { |
1202 | struct se_device *dev = task->task_se_cmd->se_dev; | 1195 | struct se_device *dev = task->task_se_cmd->se_dev; |
1203 | 1196 | ||
@@ -1211,97 +1204,13 @@ target_emulate_synchronize_cache(struct se_task *task) | |||
1211 | return 0; | 1204 | return 0; |
1212 | } | 1205 | } |
1213 | 1206 | ||
1214 | static int | 1207 | int target_emulate_noop(struct se_task *task) |
1215 | target_emulate_noop(struct se_task *task) | ||
1216 | { | 1208 | { |
1217 | task->task_scsi_status = GOOD; | 1209 | task->task_scsi_status = GOOD; |
1218 | transport_complete_task(task, 1); | 1210 | transport_complete_task(task, 1); |
1219 | return 0; | 1211 | return 0; |
1220 | } | 1212 | } |
1221 | 1213 | ||
1222 | int | ||
1223 | transport_emulate_control_cdb(struct se_task *task) | ||
1224 | { | ||
1225 | struct se_cmd *cmd = task->task_se_cmd; | ||
1226 | struct se_device *dev = cmd->se_dev; | ||
1227 | unsigned short service_action; | ||
1228 | int ret = 0; | ||
1229 | |||
1230 | switch (cmd->t_task_cdb[0]) { | ||
1231 | case INQUIRY: | ||
1232 | ret = target_emulate_inquiry(task); | ||
1233 | break; | ||
1234 | case READ_CAPACITY: | ||
1235 | ret = target_emulate_readcapacity(task); | ||
1236 | break; | ||
1237 | case MODE_SENSE: | ||
1238 | ret = target_emulate_modesense(task); | ||
1239 | break; | ||
1240 | case MODE_SENSE_10: | ||
1241 | ret = target_emulate_modesense(task); | ||
1242 | break; | ||
1243 | case SERVICE_ACTION_IN: | ||
1244 | switch (cmd->t_task_cdb[1] & 0x1f) { | ||
1245 | case SAI_READ_CAPACITY_16: | ||
1246 | ret = target_emulate_readcapacity_16(task); | ||
1247 | break; | ||
1248 | default: | ||
1249 | pr_err("Unsupported SA: 0x%02x\n", | ||
1250 | cmd->t_task_cdb[1] & 0x1f); | ||
1251 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
1252 | } | ||
1253 | break; | ||
1254 | case REQUEST_SENSE: | ||
1255 | ret = target_emulate_request_sense(task); | ||
1256 | break; | ||
1257 | case UNMAP: | ||
1258 | ret = target_emulate_unmap(task); | ||
1259 | break; | ||
1260 | case WRITE_SAME: | ||
1261 | ret = target_emulate_write_same(task); | ||
1262 | break; | ||
1263 | case WRITE_SAME_16: | ||
1264 | ret = target_emulate_write_same(task); | ||
1265 | break; | ||
1266 | case VARIABLE_LENGTH_CMD: | ||
1267 | service_action = | ||
1268 | get_unaligned_be16(&cmd->t_task_cdb[8]); | ||
1269 | switch (service_action) { | ||
1270 | case WRITE_SAME_32: | ||
1271 | ret = target_emulate_write_same(task); | ||
1272 | break; | ||
1273 | default: | ||
1274 | pr_err("Unsupported VARIABLE_LENGTH_CMD SA:" | ||
1275 | " 0x%02x\n", service_action); | ||
1276 | break; | ||
1277 | } | ||
1278 | break; | ||
1279 | case SYNCHRONIZE_CACHE: | ||
1280 | case 0x91: /* SYNCHRONIZE_CACHE_16: */ | ||
1281 | ret = target_emulate_synchronize_cache(task); | ||
1282 | break; | ||
1283 | case ALLOW_MEDIUM_REMOVAL: | ||
1284 | case ERASE: | ||
1285 | case REZERO_UNIT: | ||
1286 | case SEEK_10: | ||
1287 | case SPACE: | ||
1288 | case START_STOP: | ||
1289 | case TEST_UNIT_READY: | ||
1290 | case VERIFY: | ||
1291 | case WRITE_FILEMARKS: | ||
1292 | ret = target_emulate_noop(task); | ||
1293 | break; | ||
1294 | default: | ||
1295 | pr_err("Unsupported SCSI Opcode: 0x%02x for %s\n", | ||
1296 | cmd->t_task_cdb[0], dev->transport->name); | ||
1297 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
1298 | } | ||
1299 | |||
1300 | if (ret < 0) | ||
1301 | return ret; | ||
1302 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | ||
1303 | } | ||
1304 | |||
1305 | /* | 1214 | /* |
1306 | * Write a CDB into @cdb that is based on the one the intiator sent us, | 1215 | * Write a CDB into @cdb that is based on the one the intiator sent us, |
1307 | * but updated to only cover the sectors that the current task handles. | 1216 | * but updated to only cover the sectors that the current task handles. |
diff --git a/drivers/target/target_core_cdb.h b/drivers/target/target_core_cdb.h new file mode 100644 index 000000000000..ad6b1e393001 --- /dev/null +++ b/drivers/target/target_core_cdb.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef TARGET_CORE_CDB_H | ||
2 | #define TARGET_CORE_CDB_H | ||
3 | |||
4 | int target_emulate_inquiry(struct se_task *task); | ||
5 | int target_emulate_readcapacity(struct se_task *task); | ||
6 | int target_emulate_readcapacity_16(struct se_task *task); | ||
7 | int target_emulate_modesense(struct se_task *task); | ||
8 | int target_emulate_request_sense(struct se_task *task); | ||
9 | int target_emulate_unmap(struct se_task *task); | ||
10 | int target_emulate_write_same(struct se_task *task); | ||
11 | int target_emulate_synchronize_cache(struct se_task *task); | ||
12 | int target_emulate_noop(struct se_task *task); | ||
13 | |||
14 | #endif /* TARGET_CORE_CDB_H */ | ||
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 74015793c03a..f603b12485bd 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <target/target_core_configfs.h> | 52 | #include <target/target_core_configfs.h> |
53 | 53 | ||
54 | #include "target_core_alua.h" | 54 | #include "target_core_alua.h" |
55 | #include "target_core_cdb.h" | ||
55 | #include "target_core_hba.h" | 56 | #include "target_core_hba.h" |
56 | #include "target_core_pr.h" | 57 | #include "target_core_pr.h" |
57 | #include "target_core_ua.h" | 58 | #include "target_core_ua.h" |
@@ -2155,31 +2156,11 @@ check_depth: | |||
2155 | atomic_set(&cmd->t_transport_sent, 1); | 2156 | atomic_set(&cmd->t_transport_sent, 1); |
2156 | 2157 | ||
2157 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 2158 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
2158 | /* | ||
2159 | * The struct se_cmd->execute_task() function pointer is used | ||
2160 | * to grab REPORT_LUNS and other CDBs we want to handle before they hit the | ||
2161 | * struct se_subsystem_api->do_task() caller below. | ||
2162 | */ | ||
2163 | if (cmd->execute_task) { | ||
2164 | error = cmd->execute_task(task); | ||
2165 | } else { | ||
2166 | /* | ||
2167 | * Currently for all virtual TCM plugins including IBLOCK, FILEIO and | ||
2168 | * RAMDISK we use the internal transport_emulate_control_cdb() logic | ||
2169 | * with struct se_subsystem_api callers for the primary SPC-3 TYPE_DISK | ||
2170 | * LUN emulation code. | ||
2171 | * | ||
2172 | * For TCM/pSCSI and all other SCF_SCSI_DATA_SG_IO_CDB I/O tasks we | ||
2173 | * call ->do_task() directly and let the underlying TCM subsystem plugin | ||
2174 | * code handle the CDB emulation. | ||
2175 | */ | ||
2176 | if ((dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) && | ||
2177 | (!(task->task_se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB))) | ||
2178 | error = transport_emulate_control_cdb(task); | ||
2179 | else | ||
2180 | error = dev->transport->do_task(task); | ||
2181 | } | ||
2182 | 2159 | ||
2160 | if (cmd->execute_task) | ||
2161 | error = cmd->execute_task(task); | ||
2162 | else | ||
2163 | error = dev->transport->do_task(task); | ||
2183 | if (error != 0) { | 2164 | if (error != 0) { |
2184 | cmd->transport_error_status = error; | 2165 | cmd->transport_error_status = error; |
2185 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 2166 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
@@ -2622,6 +2603,13 @@ static int transport_generic_cmd_sequencer( | |||
2622 | */ | 2603 | */ |
2623 | } | 2604 | } |
2624 | 2605 | ||
2606 | /* | ||
2607 | * If we operate in passthrough mode we skip most CDB emulation and | ||
2608 | * instead hand the commands down to the physical SCSI device. | ||
2609 | */ | ||
2610 | passthrough = | ||
2611 | (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV); | ||
2612 | |||
2625 | switch (cdb[0]) { | 2613 | switch (cdb[0]) { |
2626 | case READ_6: | 2614 | case READ_6: |
2627 | sectors = transport_get_sectors_6(cdb, cmd, §or_ret); | 2615 | sectors = transport_get_sectors_6(cdb, cmd, §or_ret); |
@@ -2701,9 +2689,12 @@ static int transport_generic_cmd_sequencer( | |||
2701 | cmd->t_task_lba = transport_lba_32(cdb); | 2689 | cmd->t_task_lba = transport_lba_32(cdb); |
2702 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; | 2690 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; |
2703 | 2691 | ||
2704 | if (dev->transport->transport_type == | 2692 | /* |
2705 | TRANSPORT_PLUGIN_PHBA_PDEV) | 2693 | * Do now allow BIDI commands for passthrough mode. |
2694 | */ | ||
2695 | if (passthrough) | ||
2706 | goto out_unsupported_cdb; | 2696 | goto out_unsupported_cdb; |
2697 | |||
2707 | /* | 2698 | /* |
2708 | * Setup BIDI XOR callback to be run after I/O completion. | 2699 | * Setup BIDI XOR callback to be run after I/O completion. |
2709 | */ | 2700 | */ |
@@ -2712,13 +2703,6 @@ static int transport_generic_cmd_sequencer( | |||
2712 | break; | 2703 | break; |
2713 | case VARIABLE_LENGTH_CMD: | 2704 | case VARIABLE_LENGTH_CMD: |
2714 | service_action = get_unaligned_be16(&cdb[8]); | 2705 | service_action = get_unaligned_be16(&cdb[8]); |
2715 | /* | ||
2716 | * Determine if this is TCM/PSCSI device and we should disable | ||
2717 | * internal emulation for this CDB. | ||
2718 | */ | ||
2719 | passthrough = (dev->transport->transport_type == | ||
2720 | TRANSPORT_PLUGIN_PHBA_PDEV); | ||
2721 | |||
2722 | switch (service_action) { | 2706 | switch (service_action) { |
2723 | case XDWRITEREAD_32: | 2707 | case XDWRITEREAD_32: |
2724 | sectors = transport_get_sectors_32(cdb, cmd, §or_ret); | 2708 | sectors = transport_get_sectors_32(cdb, cmd, §or_ret); |
@@ -2732,8 +2716,12 @@ static int transport_generic_cmd_sequencer( | |||
2732 | cmd->t_task_lba = transport_lba_64_ext(cdb); | 2716 | cmd->t_task_lba = transport_lba_64_ext(cdb); |
2733 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; | 2717 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; |
2734 | 2718 | ||
2719 | /* | ||
2720 | * Do now allow BIDI commands for passthrough mode. | ||
2721 | */ | ||
2735 | if (passthrough) | 2722 | if (passthrough) |
2736 | goto out_unsupported_cdb; | 2723 | goto out_unsupported_cdb; |
2724 | |||
2737 | /* | 2725 | /* |
2738 | * Setup BIDI XOR callback to be run during after I/O | 2726 | * Setup BIDI XOR callback to be run during after I/O |
2739 | * completion. | 2727 | * completion. |
@@ -2759,7 +2747,8 @@ static int transport_generic_cmd_sequencer( | |||
2759 | 2747 | ||
2760 | if (target_check_write_same_discard(&cdb[10], dev) < 0) | 2748 | if (target_check_write_same_discard(&cdb[10], dev) < 0) |
2761 | goto out_invalid_cdb_field; | 2749 | goto out_invalid_cdb_field; |
2762 | 2750 | if (!passthrough) | |
2751 | cmd->execute_task = target_emulate_write_same; | ||
2763 | break; | 2752 | break; |
2764 | default: | 2753 | default: |
2765 | pr_err("VARIABLE_LENGTH_CMD service action" | 2754 | pr_err("VARIABLE_LENGTH_CMD service action" |
@@ -2797,8 +2786,15 @@ static int transport_generic_cmd_sequencer( | |||
2797 | case MODE_SENSE: | 2786 | case MODE_SENSE: |
2798 | size = cdb[4]; | 2787 | size = cdb[4]; |
2799 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; | 2788 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; |
2789 | if (!passthrough) | ||
2790 | cmd->execute_task = target_emulate_modesense; | ||
2800 | break; | 2791 | break; |
2801 | case MODE_SENSE_10: | 2792 | case MODE_SENSE_10: |
2793 | size = (cdb[7] << 8) + cdb[8]; | ||
2794 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; | ||
2795 | if (!passthrough) | ||
2796 | cmd->execute_task = target_emulate_modesense; | ||
2797 | break; | ||
2802 | case GPCMD_READ_BUFFER_CAPACITY: | 2798 | case GPCMD_READ_BUFFER_CAPACITY: |
2803 | case GPCMD_SEND_OPC: | 2799 | case GPCMD_SEND_OPC: |
2804 | case LOG_SELECT: | 2800 | case LOG_SELECT: |
@@ -2867,6 +2863,8 @@ static int transport_generic_cmd_sequencer( | |||
2867 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) | 2863 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) |
2868 | cmd->sam_task_attr = MSG_HEAD_TAG; | 2864 | cmd->sam_task_attr = MSG_HEAD_TAG; |
2869 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; | 2865 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; |
2866 | if (!passthrough) | ||
2867 | cmd->execute_task = target_emulate_inquiry; | ||
2870 | break; | 2868 | break; |
2871 | case READ_BUFFER: | 2869 | case READ_BUFFER: |
2872 | size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; | 2870 | size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; |
@@ -2875,6 +2873,8 @@ static int transport_generic_cmd_sequencer( | |||
2875 | case READ_CAPACITY: | 2873 | case READ_CAPACITY: |
2876 | size = READ_CAP_LEN; | 2874 | size = READ_CAP_LEN; |
2877 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; | 2875 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; |
2876 | if (!passthrough) | ||
2877 | cmd->execute_task = target_emulate_readcapacity; | ||
2878 | break; | 2878 | break; |
2879 | case READ_MEDIA_SERIAL_NUMBER: | 2879 | case READ_MEDIA_SERIAL_NUMBER: |
2880 | case SECURITY_PROTOCOL_IN: | 2880 | case SECURITY_PROTOCOL_IN: |
@@ -2883,6 +2883,21 @@ static int transport_generic_cmd_sequencer( | |||
2883 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; | 2883 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; |
2884 | break; | 2884 | break; |
2885 | case SERVICE_ACTION_IN: | 2885 | case SERVICE_ACTION_IN: |
2886 | switch (cmd->t_task_cdb[1] & 0x1f) { | ||
2887 | case SAI_READ_CAPACITY_16: | ||
2888 | if (!passthrough) | ||
2889 | cmd->execute_task = | ||
2890 | target_emulate_readcapacity_16; | ||
2891 | break; | ||
2892 | default: | ||
2893 | if (passthrough) | ||
2894 | break; | ||
2895 | |||
2896 | pr_err("Unsupported SA: 0x%02x\n", | ||
2897 | cmd->t_task_cdb[1] & 0x1f); | ||
2898 | goto out_unsupported_cdb; | ||
2899 | } | ||
2900 | /*FALLTHROUGH*/ | ||
2886 | case ACCESS_CONTROL_IN: | 2901 | case ACCESS_CONTROL_IN: |
2887 | case ACCESS_CONTROL_OUT: | 2902 | case ACCESS_CONTROL_OUT: |
2888 | case EXTENDED_COPY: | 2903 | case EXTENDED_COPY: |
@@ -2913,6 +2928,8 @@ static int transport_generic_cmd_sequencer( | |||
2913 | case REQUEST_SENSE: | 2928 | case REQUEST_SENSE: |
2914 | size = cdb[4]; | 2929 | size = cdb[4]; |
2915 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; | 2930 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; |
2931 | if (!passthrough) | ||
2932 | cmd->execute_task = target_emulate_request_sense; | ||
2916 | break; | 2933 | break; |
2917 | case READ_ELEMENT_STATUS: | 2934 | case READ_ELEMENT_STATUS: |
2918 | size = 65536 * cdb[7] + 256 * cdb[8] + cdb[9]; | 2935 | size = 65536 * cdb[7] + 256 * cdb[8] + cdb[9]; |
@@ -2977,8 +2994,9 @@ static int transport_generic_cmd_sequencer( | |||
2977 | size = transport_get_size(sectors, cdb, cmd); | 2994 | size = transport_get_size(sectors, cdb, cmd); |
2978 | cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; | 2995 | cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; |
2979 | 2996 | ||
2980 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) | 2997 | if (passthrough) |
2981 | break; | 2998 | break; |
2999 | |||
2982 | /* | 3000 | /* |
2983 | * Check to ensure that LBA + Range does not exceed past end of | 3001 | * Check to ensure that LBA + Range does not exceed past end of |
2984 | * device for IBLOCK and FILEIO ->do_sync_cache() backend calls | 3002 | * device for IBLOCK and FILEIO ->do_sync_cache() backend calls |
@@ -2987,10 +3005,13 @@ static int transport_generic_cmd_sequencer( | |||
2987 | if (transport_cmd_get_valid_sectors(cmd) < 0) | 3005 | if (transport_cmd_get_valid_sectors(cmd) < 0) |
2988 | goto out_invalid_cdb_field; | 3006 | goto out_invalid_cdb_field; |
2989 | } | 3007 | } |
3008 | cmd->execute_task = target_emulate_synchronize_cache; | ||
2990 | break; | 3009 | break; |
2991 | case UNMAP: | 3010 | case UNMAP: |
2992 | size = get_unaligned_be16(&cdb[7]); | 3011 | size = get_unaligned_be16(&cdb[7]); |
2993 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; | 3012 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; |
3013 | if (!passthrough) | ||
3014 | cmd->execute_task = target_emulate_unmap; | ||
2994 | break; | 3015 | break; |
2995 | case WRITE_SAME_16: | 3016 | case WRITE_SAME_16: |
2996 | sectors = transport_get_sectors_16(cdb, cmd, §or_ret); | 3017 | sectors = transport_get_sectors_16(cdb, cmd, §or_ret); |
@@ -3009,6 +3030,8 @@ static int transport_generic_cmd_sequencer( | |||
3009 | 3030 | ||
3010 | if (target_check_write_same_discard(&cdb[1], dev) < 0) | 3031 | if (target_check_write_same_discard(&cdb[1], dev) < 0) |
3011 | goto out_invalid_cdb_field; | 3032 | goto out_invalid_cdb_field; |
3033 | if (!passthrough) | ||
3034 | cmd->execute_task = target_emulate_write_same; | ||
3012 | break; | 3035 | break; |
3013 | case WRITE_SAME: | 3036 | case WRITE_SAME: |
3014 | sectors = transport_get_sectors_10(cdb, cmd, §or_ret); | 3037 | sectors = transport_get_sectors_10(cdb, cmd, §or_ret); |
@@ -3030,20 +3053,26 @@ static int transport_generic_cmd_sequencer( | |||
3030 | */ | 3053 | */ |
3031 | if (target_check_write_same_discard(&cdb[1], dev) < 0) | 3054 | if (target_check_write_same_discard(&cdb[1], dev) < 0) |
3032 | goto out_invalid_cdb_field; | 3055 | goto out_invalid_cdb_field; |
3056 | if (!passthrough) | ||
3057 | cmd->execute_task = target_emulate_write_same; | ||
3033 | break; | 3058 | break; |
3034 | case ALLOW_MEDIUM_REMOVAL: | 3059 | case ALLOW_MEDIUM_REMOVAL: |
3035 | case GPCMD_CLOSE_TRACK: | ||
3036 | case ERASE: | 3060 | case ERASE: |
3037 | case INITIALIZE_ELEMENT_STATUS: | ||
3038 | case GPCMD_LOAD_UNLOAD: | ||
3039 | case REZERO_UNIT: | 3061 | case REZERO_UNIT: |
3040 | case SEEK_10: | 3062 | case SEEK_10: |
3041 | case GPCMD_SET_SPEED: | ||
3042 | case SPACE: | 3063 | case SPACE: |
3043 | case START_STOP: | 3064 | case START_STOP: |
3044 | case TEST_UNIT_READY: | 3065 | case TEST_UNIT_READY: |
3045 | case VERIFY: | 3066 | case VERIFY: |
3046 | case WRITE_FILEMARKS: | 3067 | case WRITE_FILEMARKS: |
3068 | cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; | ||
3069 | if (!passthrough) | ||
3070 | cmd->execute_task = target_emulate_noop; | ||
3071 | break; | ||
3072 | case GPCMD_CLOSE_TRACK: | ||
3073 | case INITIALIZE_ELEMENT_STATUS: | ||
3074 | case GPCMD_LOAD_UNLOAD: | ||
3075 | case GPCMD_SET_SPEED: | ||
3047 | case MOVE_MEDIUM: | 3076 | case MOVE_MEDIUM: |
3048 | cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; | 3077 | cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; |
3049 | break; | 3078 | break; |
@@ -3100,6 +3129,11 @@ static int transport_generic_cmd_sequencer( | |||
3100 | cmd->data_length = size; | 3129 | cmd->data_length = size; |
3101 | } | 3130 | } |
3102 | 3131 | ||
3132 | /* reject any command that we don't have a handler for */ | ||
3133 | if (!(passthrough || cmd->execute_task || | ||
3134 | (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB))) | ||
3135 | goto out_unsupported_cdb; | ||
3136 | |||
3103 | /* Let's limit control cdbs to a page, for simplicity's sake. */ | 3137 | /* Let's limit control cdbs to a page, for simplicity's sake. */ |
3104 | if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) && | 3138 | if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) && |
3105 | size > PAGE_SIZE) | 3139 | size > PAGE_SIZE) |