diff options
| -rw-r--r-- | drivers/target/target_core_cdb.c | 105 |
1 files changed, 59 insertions, 46 deletions
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 38535eb13929..ff2dfa383735 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c | |||
| @@ -680,8 +680,9 @@ target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) | |||
| 680 | } | 680 | } |
| 681 | 681 | ||
| 682 | static int | 682 | static int |
| 683 | target_emulate_inquiry(struct se_cmd *cmd) | 683 | target_emulate_inquiry(struct se_task *task) |
| 684 | { | 684 | { |
| 685 | struct se_cmd *cmd = task->task_se_cmd; | ||
| 685 | struct se_device *dev = cmd->se_dev; | 686 | struct se_device *dev = cmd->se_dev; |
| 686 | unsigned char *buf; | 687 | unsigned char *buf; |
| 687 | unsigned char *cdb = cmd->t_task_cdb; | 688 | unsigned char *cdb = cmd->t_task_cdb; |
| @@ -721,8 +722,9 @@ target_emulate_inquiry(struct se_cmd *cmd) | |||
| 721 | } | 722 | } |
| 722 | 723 | ||
| 723 | static int | 724 | static int |
| 724 | target_emulate_readcapacity(struct se_cmd *cmd) | 725 | target_emulate_readcapacity(struct se_task *task) |
| 725 | { | 726 | { |
| 727 | struct se_cmd *cmd = task->task_se_cmd; | ||
| 726 | struct se_device *dev = cmd->se_dev; | 728 | struct se_device *dev = cmd->se_dev; |
| 727 | unsigned char *buf; | 729 | unsigned char *buf; |
| 728 | unsigned long long blocks_long = dev->transport->get_blocks(dev); | 730 | unsigned long long blocks_long = dev->transport->get_blocks(dev); |
| @@ -755,8 +757,9 @@ target_emulate_readcapacity(struct se_cmd *cmd) | |||
| 755 | } | 757 | } |
| 756 | 758 | ||
| 757 | static int | 759 | static int |
| 758 | target_emulate_readcapacity_16(struct se_cmd *cmd) | 760 | target_emulate_readcapacity_16(struct se_task *task) |
| 759 | { | 761 | { |
| 762 | struct se_cmd *cmd = task->task_se_cmd; | ||
| 760 | struct se_device *dev = cmd->se_dev; | 763 | struct se_device *dev = cmd->se_dev; |
| 761 | unsigned char *buf; | 764 | unsigned char *buf; |
| 762 | unsigned long long blocks = dev->transport->get_blocks(dev); | 765 | unsigned long long blocks = dev->transport->get_blocks(dev); |
| @@ -923,13 +926,15 @@ target_modesense_dpofua(unsigned char *buf, int type) | |||
| 923 | } | 926 | } |
| 924 | 927 | ||
| 925 | static int | 928 | static int |
| 926 | target_emulate_modesense(struct se_cmd *cmd, int ten) | 929 | target_emulate_modesense(struct se_task *task) |
| 927 | { | 930 | { |
| 931 | struct se_cmd *cmd = task->task_se_cmd; | ||
| 928 | struct se_device *dev = cmd->se_dev; | 932 | struct se_device *dev = cmd->se_dev; |
| 929 | char *cdb = cmd->t_task_cdb; | 933 | char *cdb = cmd->t_task_cdb; |
| 930 | unsigned char *rbuf; | 934 | unsigned char *rbuf; |
| 931 | int type = dev->transport->get_device_type(dev); | 935 | int type = dev->transport->get_device_type(dev); |
| 932 | int offset = (ten) ? 8 : 4; | 936 | int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10); |
| 937 | int offset = ten ? 8 : 4; | ||
| 933 | int length = 0; | 938 | int length = 0; |
| 934 | unsigned char buf[SE_MODE_PAGE_BUF]; | 939 | unsigned char buf[SE_MODE_PAGE_BUF]; |
| 935 | 940 | ||
| @@ -999,8 +1004,9 @@ target_emulate_modesense(struct se_cmd *cmd, int ten) | |||
| 999 | } | 1004 | } |
| 1000 | 1005 | ||
| 1001 | static int | 1006 | static int |
| 1002 | target_emulate_request_sense(struct se_cmd *cmd) | 1007 | target_emulate_request_sense(struct se_task *task) |
| 1003 | { | 1008 | { |
| 1009 | struct se_cmd *cmd = task->task_se_cmd; | ||
| 1004 | unsigned char *cdb = cmd->t_task_cdb; | 1010 | unsigned char *cdb = cmd->t_task_cdb; |
| 1005 | unsigned char *buf; | 1011 | unsigned char *buf; |
| 1006 | u8 ua_asc = 0, ua_ascq = 0; | 1012 | u8 ua_asc = 0, ua_ascq = 0; |
| @@ -1079,6 +1085,12 @@ target_emulate_unmap(struct se_task *task) | |||
| 1079 | int ret = 0, offset; | 1085 | int ret = 0, offset; |
| 1080 | unsigned short dl, bd_dl; | 1086 | unsigned short dl, bd_dl; |
| 1081 | 1087 | ||
| 1088 | if (!dev->transport->do_discard) { | ||
| 1089 | pr_err("UNMAP emulation not supported for: %s\n", | ||
| 1090 | dev->transport->name); | ||
| 1091 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
| 1092 | } | ||
| 1093 | |||
| 1082 | /* First UNMAP block descriptor starts at 8 byte offset */ | 1094 | /* First UNMAP block descriptor starts at 8 byte offset */ |
| 1083 | offset = 8; | 1095 | offset = 8; |
| 1084 | size -= 8; | 1096 | size -= 8; |
| @@ -1119,13 +1131,28 @@ err: | |||
| 1119 | * Note this is not used for TCM/pSCSI passthrough | 1131 | * Note this is not used for TCM/pSCSI passthrough |
| 1120 | */ | 1132 | */ |
| 1121 | static int | 1133 | static int |
| 1122 | target_emulate_write_same(struct se_task *task, u32 num_blocks) | 1134 | target_emulate_write_same(struct se_task *task) |
| 1123 | { | 1135 | { |
| 1124 | struct se_cmd *cmd = task->task_se_cmd; | 1136 | struct se_cmd *cmd = task->task_se_cmd; |
| 1125 | struct se_device *dev = cmd->se_dev; | 1137 | struct se_device *dev = cmd->se_dev; |
| 1126 | sector_t range; | 1138 | sector_t range; |
| 1127 | sector_t lba = cmd->t_task_lba; | 1139 | sector_t lba = cmd->t_task_lba; |
| 1140 | u32 num_blocks; | ||
| 1128 | int ret; | 1141 | int ret; |
| 1142 | |||
| 1143 | if (!dev->transport->do_discard) { | ||
| 1144 | pr_err("WRITE_SAME emulation not supported" | ||
| 1145 | " for: %s\n", dev->transport->name); | ||
| 1146 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | if (cmd->t_task_cdb[0] == WRITE_SAME) | ||
| 1150 | num_blocks = get_unaligned_be16(&cmd->t_task_cdb[7]); | ||
| 1151 | else if (cmd->t_task_cdb[0] == WRITE_SAME_16) | ||
| 1152 | num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]); | ||
| 1153 | else /* WRITE_SAME_32 via VARIABLE_LENGTH_CMD */ | ||
| 1154 | num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]); | ||
| 1155 | |||
| 1129 | /* | 1156 | /* |
| 1130 | * Use the explicit range when non zero is supplied, otherwise calculate | 1157 | * Use the explicit range when non zero is supplied, otherwise calculate |
| 1131 | * the remaining range based on ->get_blocks() - starting LBA. | 1158 | * the remaining range based on ->get_blocks() - starting LBA. |
| @@ -1147,6 +1174,21 @@ target_emulate_write_same(struct se_task *task, u32 num_blocks) | |||
| 1147 | return 0; | 1174 | return 0; |
| 1148 | } | 1175 | } |
| 1149 | 1176 | ||
| 1177 | static int | ||
| 1178 | target_emulate_synchronize_cache(struct se_task *task) | ||
| 1179 | { | ||
| 1180 | struct se_device *dev = task->task_se_cmd->se_dev; | ||
| 1181 | |||
| 1182 | if (!dev->transport->do_sync_cache) { | ||
| 1183 | pr_err("SYNCHRONIZE_CACHE emulation not supported" | ||
| 1184 | " for: %s\n", dev->transport->name); | ||
| 1185 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
| 1186 | } | ||
| 1187 | |||
| 1188 | dev->transport->do_sync_cache(task); | ||
| 1189 | return 0; | ||
| 1190 | } | ||
| 1191 | |||
| 1150 | int | 1192 | int |
| 1151 | transport_emulate_control_cdb(struct se_task *task) | 1193 | transport_emulate_control_cdb(struct se_task *task) |
| 1152 | { | 1194 | { |
| @@ -1157,21 +1199,21 @@ transport_emulate_control_cdb(struct se_task *task) | |||
| 1157 | 1199 | ||
| 1158 | switch (cmd->t_task_cdb[0]) { | 1200 | switch (cmd->t_task_cdb[0]) { |
| 1159 | case INQUIRY: | 1201 | case INQUIRY: |
| 1160 | ret = target_emulate_inquiry(cmd); | 1202 | ret = target_emulate_inquiry(task); |
| 1161 | break; | 1203 | break; |
| 1162 | case READ_CAPACITY: | 1204 | case READ_CAPACITY: |
| 1163 | ret = target_emulate_readcapacity(cmd); | 1205 | ret = target_emulate_readcapacity(task); |
| 1164 | break; | 1206 | break; |
| 1165 | case MODE_SENSE: | 1207 | case MODE_SENSE: |
| 1166 | ret = target_emulate_modesense(cmd, 0); | 1208 | ret = target_emulate_modesense(task); |
| 1167 | break; | 1209 | break; |
| 1168 | case MODE_SENSE_10: | 1210 | case MODE_SENSE_10: |
| 1169 | ret = target_emulate_modesense(cmd, 1); | 1211 | ret = target_emulate_modesense(task); |
| 1170 | break; | 1212 | break; |
| 1171 | case SERVICE_ACTION_IN: | 1213 | case SERVICE_ACTION_IN: |
| 1172 | switch (cmd->t_task_cdb[1] & 0x1f) { | 1214 | switch (cmd->t_task_cdb[1] & 0x1f) { |
| 1173 | case SAI_READ_CAPACITY_16: | 1215 | case SAI_READ_CAPACITY_16: |
| 1174 | ret = target_emulate_readcapacity_16(cmd); | 1216 | ret = target_emulate_readcapacity_16(task); |
| 1175 | break; | 1217 | break; |
| 1176 | default: | 1218 | default: |
| 1177 | pr_err("Unsupported SA: 0x%02x\n", | 1219 | pr_err("Unsupported SA: 0x%02x\n", |
| @@ -1180,47 +1222,23 @@ transport_emulate_control_cdb(struct se_task *task) | |||
| 1180 | } | 1222 | } |
| 1181 | break; | 1223 | break; |
| 1182 | case REQUEST_SENSE: | 1224 | case REQUEST_SENSE: |
| 1183 | ret = target_emulate_request_sense(cmd); | 1225 | ret = target_emulate_request_sense(task); |
| 1184 | break; | 1226 | break; |
| 1185 | case UNMAP: | 1227 | case UNMAP: |
| 1186 | if (!dev->transport->do_discard) { | ||
| 1187 | pr_err("UNMAP emulation not supported for: %s\n", | ||
| 1188 | dev->transport->name); | ||
| 1189 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
| 1190 | } | ||
| 1191 | ret = target_emulate_unmap(task); | 1228 | ret = target_emulate_unmap(task); |
| 1192 | break; | 1229 | break; |
| 1193 | case WRITE_SAME: | 1230 | case WRITE_SAME: |
| 1194 | if (!dev->transport->do_discard) { | 1231 | ret = target_emulate_write_same(task); |
| 1195 | pr_err("WRITE_SAME emulation not supported" | ||
| 1196 | " for: %s\n", dev->transport->name); | ||
| 1197 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
| 1198 | } | ||
| 1199 | ret = target_emulate_write_same(task, | ||
| 1200 | get_unaligned_be16(&cmd->t_task_cdb[7])); | ||
| 1201 | break; | 1232 | break; |
| 1202 | case WRITE_SAME_16: | 1233 | case WRITE_SAME_16: |
| 1203 | if (!dev->transport->do_discard) { | 1234 | ret = target_emulate_write_same(task); |
| 1204 | pr_err("WRITE_SAME_16 emulation not supported" | ||
| 1205 | " for: %s\n", dev->transport->name); | ||
| 1206 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
| 1207 | } | ||
| 1208 | ret = target_emulate_write_same(task, | ||
| 1209 | get_unaligned_be32(&cmd->t_task_cdb[10])); | ||
| 1210 | break; | 1235 | break; |
| 1211 | case VARIABLE_LENGTH_CMD: | 1236 | case VARIABLE_LENGTH_CMD: |
| 1212 | service_action = | 1237 | service_action = |
| 1213 | get_unaligned_be16(&cmd->t_task_cdb[8]); | 1238 | get_unaligned_be16(&cmd->t_task_cdb[8]); |
| 1214 | switch (service_action) { | 1239 | switch (service_action) { |
| 1215 | case WRITE_SAME_32: | 1240 | case WRITE_SAME_32: |
| 1216 | if (!dev->transport->do_discard) { | 1241 | ret = target_emulate_write_same(task); |
| 1217 | pr_err("WRITE_SAME_32 SA emulation not" | ||
| 1218 | " supported for: %s\n", | ||
| 1219 | dev->transport->name); | ||
| 1220 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
| 1221 | } | ||
| 1222 | ret = target_emulate_write_same(task, | ||
| 1223 | get_unaligned_be32(&cmd->t_task_cdb[28])); | ||
| 1224 | break; | 1242 | break; |
| 1225 | default: | 1243 | default: |
| 1226 | pr_err("Unsupported VARIABLE_LENGTH_CMD SA:" | 1244 | pr_err("Unsupported VARIABLE_LENGTH_CMD SA:" |
| @@ -1230,12 +1248,7 @@ transport_emulate_control_cdb(struct se_task *task) | |||
| 1230 | break; | 1248 | break; |
| 1231 | case SYNCHRONIZE_CACHE: | 1249 | case SYNCHRONIZE_CACHE: |
| 1232 | case 0x91: /* SYNCHRONIZE_CACHE_16: */ | 1250 | case 0x91: /* SYNCHRONIZE_CACHE_16: */ |
| 1233 | if (!dev->transport->do_sync_cache) { | 1251 | ret = target_emulate_synchronize_cache(task); |
| 1234 | pr_err("SYNCHRONIZE_CACHE emulation not supported" | ||
| 1235 | " for: %s\n", dev->transport->name); | ||
| 1236 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
| 1237 | } | ||
| 1238 | dev->transport->do_sync_cache(task); | ||
| 1239 | break; | 1252 | break; |
| 1240 | case ALLOW_MEDIUM_REMOVAL: | 1253 | case ALLOW_MEDIUM_REMOVAL: |
| 1241 | case ERASE: | 1254 | case ERASE: |
