diff options
| -rw-r--r-- | drivers/target/target_core_alua.c | 5 | ||||
| -rw-r--r-- | drivers/target/target_core_cdb.c | 58 | ||||
| -rw-r--r-- | drivers/target/target_core_device.c | 2 | ||||
| -rw-r--r-- | drivers/target/target_core_pr.c | 129 | ||||
| -rw-r--r-- | drivers/target/target_core_transport.c | 47 | ||||
| -rw-r--r-- | include/target/target_core_base.h | 1 |
6 files changed, 142 insertions, 100 deletions
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 14668d05ea0d..2739b93983a2 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
| @@ -165,6 +165,8 @@ int target_emulate_report_target_port_groups(struct se_task *task) | |||
| 165 | 165 | ||
| 166 | transport_kunmap_first_data_page(cmd); | 166 | transport_kunmap_first_data_page(cmd); |
| 167 | 167 | ||
| 168 | task->task_scsi_status = GOOD; | ||
| 169 | transport_complete_task(task, 1); | ||
| 168 | return 0; | 170 | return 0; |
| 169 | } | 171 | } |
| 170 | 172 | ||
| @@ -343,7 +345,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
| 343 | 345 | ||
| 344 | out: | 346 | out: |
| 345 | transport_kunmap_first_data_page(cmd); | 347 | transport_kunmap_first_data_page(cmd); |
| 346 | 348 | task->task_scsi_status = GOOD; | |
| 349 | transport_complete_task(task, 1); | ||
| 347 | return 0; | 350 | return 0; |
| 348 | } | 351 | } |
| 349 | 352 | ||
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index ff2dfa383735..5a03085304e5 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c | |||
| @@ -688,8 +688,10 @@ target_emulate_inquiry(struct se_task *task) | |||
| 688 | unsigned char *cdb = cmd->t_task_cdb; | 688 | unsigned char *cdb = cmd->t_task_cdb; |
| 689 | int p, ret; | 689 | int p, ret; |
| 690 | 690 | ||
| 691 | if (!(cdb[1] & 0x1)) | 691 | if (!(cdb[1] & 0x1)) { |
| 692 | return target_emulate_inquiry_std(cmd); | 692 | ret = target_emulate_inquiry_std(cmd); |
| 693 | goto out; | ||
| 694 | } | ||
| 693 | 695 | ||
| 694 | /* | 696 | /* |
| 695 | * Make sure we at least have 4 bytes of INQUIRY response | 697 | * Make sure we at least have 4 bytes of INQUIRY response |
| @@ -708,17 +710,25 @@ target_emulate_inquiry(struct se_task *task) | |||
| 708 | 710 | ||
| 709 | buf[0] = dev->transport->get_device_type(dev); | 711 | buf[0] = dev->transport->get_device_type(dev); |
| 710 | 712 | ||
| 711 | for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) | 713 | for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) { |
| 712 | if (cdb[2] == evpd_handlers[p].page) { | 714 | if (cdb[2] == evpd_handlers[p].page) { |
| 713 | buf[1] = cdb[2]; | 715 | buf[1] = cdb[2]; |
| 714 | ret = evpd_handlers[p].emulate(cmd, buf); | 716 | ret = evpd_handlers[p].emulate(cmd, buf); |
| 715 | transport_kunmap_first_data_page(cmd); | 717 | goto out_unmap; |
| 716 | return ret; | ||
| 717 | } | 718 | } |
| 719 | } | ||
| 718 | 720 | ||
| 719 | transport_kunmap_first_data_page(cmd); | ||
| 720 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); | 721 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); |
| 721 | return -EINVAL; | 722 | ret = -EINVAL; |
| 723 | |||
| 724 | out_unmap: | ||
| 725 | transport_kunmap_first_data_page(cmd); | ||
| 726 | out: | ||
| 727 | if (!ret) { | ||
| 728 | task->task_scsi_status = GOOD; | ||
| 729 | transport_complete_task(task, 1); | ||
| 730 | } | ||
| 731 | return ret; | ||
| 722 | } | 732 | } |
| 723 | 733 | ||
| 724 | static int | 734 | static int |
| @@ -753,6 +763,8 @@ target_emulate_readcapacity(struct se_task *task) | |||
| 753 | 763 | ||
| 754 | transport_kunmap_first_data_page(cmd); | 764 | transport_kunmap_first_data_page(cmd); |
| 755 | 765 | ||
| 766 | task->task_scsi_status = GOOD; | ||
| 767 | transport_complete_task(task, 1); | ||
| 756 | return 0; | 768 | return 0; |
| 757 | } | 769 | } |
| 758 | 770 | ||
| @@ -787,6 +799,8 @@ target_emulate_readcapacity_16(struct se_task *task) | |||
| 787 | 799 | ||
| 788 | transport_kunmap_first_data_page(cmd); | 800 | transport_kunmap_first_data_page(cmd); |
| 789 | 801 | ||
| 802 | task->task_scsi_status = GOOD; | ||
| 803 | transport_complete_task(task, 1); | ||
| 790 | return 0; | 804 | return 0; |
| 791 | } | 805 | } |
| 792 | 806 | ||
| @@ -1000,6 +1014,8 @@ target_emulate_modesense(struct se_task *task) | |||
| 1000 | memcpy(rbuf, buf, offset); | 1014 | memcpy(rbuf, buf, offset); |
| 1001 | transport_kunmap_first_data_page(cmd); | 1015 | transport_kunmap_first_data_page(cmd); |
| 1002 | 1016 | ||
| 1017 | task->task_scsi_status = GOOD; | ||
| 1018 | transport_complete_task(task, 1); | ||
| 1003 | return 0; | 1019 | return 0; |
| 1004 | } | 1020 | } |
| 1005 | 1021 | ||
| @@ -1065,7 +1081,8 @@ target_emulate_request_sense(struct se_task *task) | |||
| 1065 | 1081 | ||
| 1066 | end: | 1082 | end: |
| 1067 | transport_kunmap_first_data_page(cmd); | 1083 | transport_kunmap_first_data_page(cmd); |
| 1068 | 1084 | task->task_scsi_status = GOOD; | |
| 1085 | transport_complete_task(task, 1); | ||
| 1069 | return 0; | 1086 | return 0; |
| 1070 | } | 1087 | } |
| 1071 | 1088 | ||
| @@ -1122,7 +1139,10 @@ target_emulate_unmap(struct se_task *task) | |||
| 1122 | 1139 | ||
| 1123 | err: | 1140 | err: |
| 1124 | transport_kunmap_first_data_page(cmd); | 1141 | transport_kunmap_first_data_page(cmd); |
| 1125 | 1142 | if (!ret) { | |
| 1143 | task->task_scsi_status = GOOD; | ||
| 1144 | transport_complete_task(task, 1); | ||
| 1145 | } | ||
| 1126 | return ret; | 1146 | return ret; |
| 1127 | } | 1147 | } |
| 1128 | 1148 | ||
| @@ -1171,6 +1191,8 @@ target_emulate_write_same(struct se_task *task) | |||
| 1171 | return ret; | 1191 | return ret; |
| 1172 | } | 1192 | } |
| 1173 | 1193 | ||
| 1194 | task->task_scsi_status = GOOD; | ||
| 1195 | transport_complete_task(task, 1); | ||
| 1174 | return 0; | 1196 | return 0; |
| 1175 | } | 1197 | } |
| 1176 | 1198 | ||
| @@ -1189,6 +1211,14 @@ target_emulate_synchronize_cache(struct se_task *task) | |||
| 1189 | return 0; | 1211 | return 0; |
| 1190 | } | 1212 | } |
| 1191 | 1213 | ||
| 1214 | static int | ||
| 1215 | target_emulate_noop(struct se_task *task) | ||
| 1216 | { | ||
| 1217 | task->task_scsi_status = GOOD; | ||
| 1218 | transport_complete_task(task, 1); | ||
| 1219 | return 0; | ||
| 1220 | } | ||
| 1221 | |||
| 1192 | int | 1222 | int |
| 1193 | transport_emulate_control_cdb(struct se_task *task) | 1223 | transport_emulate_control_cdb(struct se_task *task) |
| 1194 | { | 1224 | { |
| @@ -1259,6 +1289,7 @@ transport_emulate_control_cdb(struct se_task *task) | |||
| 1259 | case TEST_UNIT_READY: | 1289 | case TEST_UNIT_READY: |
| 1260 | case VERIFY: | 1290 | case VERIFY: |
| 1261 | case WRITE_FILEMARKS: | 1291 | case WRITE_FILEMARKS: |
| 1292 | ret = target_emulate_noop(task); | ||
| 1262 | break; | 1293 | break; |
| 1263 | default: | 1294 | default: |
| 1264 | pr_err("Unsupported SCSI Opcode: 0x%02x for %s\n", | 1295 | pr_err("Unsupported SCSI Opcode: 0x%02x for %s\n", |
| @@ -1268,15 +1299,6 @@ transport_emulate_control_cdb(struct se_task *task) | |||
| 1268 | 1299 | ||
| 1269 | if (ret < 0) | 1300 | if (ret < 0) |
| 1270 | return ret; | 1301 | return ret; |
| 1271 | /* | ||
| 1272 | * Handle the successful completion here unless a caller | ||
| 1273 | * has explictly requested an asychronous completion. | ||
| 1274 | */ | ||
| 1275 | if (!(cmd->se_cmd_flags & SCF_EMULATE_CDB_ASYNC)) { | ||
| 1276 | task->task_scsi_status = GOOD; | ||
| 1277 | transport_complete_task(task, 1); | ||
| 1278 | } | ||
| 1279 | |||
| 1280 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 1302 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; |
| 1281 | } | 1303 | } |
| 1282 | 1304 | ||
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index ffbb1d6532e9..28d2c808c56b 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
| @@ -705,6 +705,8 @@ done: | |||
| 705 | buf[2] = ((lun_count >> 8) & 0xff); | 705 | buf[2] = ((lun_count >> 8) & 0xff); |
| 706 | buf[3] = (lun_count & 0xff); | 706 | buf[3] = (lun_count & 0xff); |
| 707 | 707 | ||
| 708 | se_task->task_scsi_status = GOOD; | ||
| 709 | transport_complete_task(se_task, 1); | ||
| 708 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 710 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; |
| 709 | } | 711 | } |
| 710 | 712 | ||
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 09e1e3e896c6..5a4ebfc3a54f 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
| @@ -204,23 +204,21 @@ int target_scsi2_reservation_release(struct se_task *task) | |||
| 204 | struct se_device *dev = cmd->se_dev; | 204 | struct se_device *dev = cmd->se_dev; |
| 205 | struct se_session *sess = cmd->se_sess; | 205 | struct se_session *sess = cmd->se_sess; |
| 206 | struct se_portal_group *tpg = sess->se_tpg; | 206 | struct se_portal_group *tpg = sess->se_tpg; |
| 207 | int ret; | 207 | int ret = 0; |
| 208 | 208 | ||
| 209 | if (!sess || !tpg) | 209 | if (!sess || !tpg) |
| 210 | return 0; | 210 | goto out; |
| 211 | if (target_check_scsi2_reservation_conflict(cmd, &ret)) | 211 | if (target_check_scsi2_reservation_conflict(cmd, &ret)) |
| 212 | return ret; | 212 | goto out; |
| 213 | 213 | ||
| 214 | ret = 0; | ||
| 214 | spin_lock(&dev->dev_reservation_lock); | 215 | spin_lock(&dev->dev_reservation_lock); |
| 215 | if (!dev->dev_reserved_node_acl || !sess) { | 216 | if (!dev->dev_reserved_node_acl || !sess) |
| 216 | spin_unlock(&dev->dev_reservation_lock); | 217 | goto out_unlock; |
| 217 | return 0; | 218 | |
| 218 | } | 219 | if (dev->dev_reserved_node_acl != sess->se_node_acl) |
| 220 | goto out_unlock; | ||
| 219 | 221 | ||
| 220 | if (dev->dev_reserved_node_acl != sess->se_node_acl) { | ||
| 221 | spin_unlock(&dev->dev_reservation_lock); | ||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | dev->dev_reserved_node_acl = NULL; | 222 | dev->dev_reserved_node_acl = NULL; |
| 225 | dev->dev_flags &= ~DF_SPC2_RESERVATIONS; | 223 | dev->dev_flags &= ~DF_SPC2_RESERVATIONS; |
| 226 | if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) { | 224 | if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) { |
| @@ -231,9 +229,15 @@ int target_scsi2_reservation_release(struct se_task *task) | |||
| 231 | " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(), | 229 | " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(), |
| 232 | cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, | 230 | cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, |
| 233 | sess->se_node_acl->initiatorname); | 231 | sess->se_node_acl->initiatorname); |
| 234 | spin_unlock(&dev->dev_reservation_lock); | ||
| 235 | 232 | ||
| 236 | return 0; | 233 | out_unlock: |
| 234 | spin_unlock(&dev->dev_reservation_lock); | ||
| 235 | out: | ||
| 236 | if (!ret) { | ||
| 237 | task->task_scsi_status = GOOD; | ||
| 238 | transport_complete_task(task, 1); | ||
| 239 | } | ||
| 240 | return ret; | ||
| 237 | } | 241 | } |
| 238 | 242 | ||
| 239 | int target_scsi2_reservation_reserve(struct se_task *task) | 243 | int target_scsi2_reservation_reserve(struct se_task *task) |
| @@ -242,23 +246,25 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
| 242 | struct se_device *dev = cmd->se_dev; | 246 | struct se_device *dev = cmd->se_dev; |
| 243 | struct se_session *sess = cmd->se_sess; | 247 | struct se_session *sess = cmd->se_sess; |
| 244 | struct se_portal_group *tpg = sess->se_tpg; | 248 | struct se_portal_group *tpg = sess->se_tpg; |
| 245 | int ret; | 249 | int ret = 0; |
| 246 | 250 | ||
| 247 | if ((cmd->t_task_cdb[1] & 0x01) && | 251 | if ((cmd->t_task_cdb[1] & 0x01) && |
| 248 | (cmd->t_task_cdb[1] & 0x02)) { | 252 | (cmd->t_task_cdb[1] & 0x02)) { |
| 249 | pr_err("LongIO and Obselete Bits set, returning" | 253 | pr_err("LongIO and Obselete Bits set, returning" |
| 250 | " ILLEGAL_REQUEST\n"); | 254 | " ILLEGAL_REQUEST\n"); |
| 251 | return PYX_TRANSPORT_ILLEGAL_REQUEST; | 255 | ret = PYX_TRANSPORT_ILLEGAL_REQUEST; |
| 256 | goto out; | ||
| 252 | } | 257 | } |
| 253 | /* | 258 | /* |
| 254 | * This is currently the case for target_core_mod passthrough struct se_cmd | 259 | * This is currently the case for target_core_mod passthrough struct se_cmd |
| 255 | * ops | 260 | * ops |
| 256 | */ | 261 | */ |
| 257 | if (!sess || !tpg) | 262 | if (!sess || !tpg) |
| 258 | return 0; | 263 | goto out; |
| 259 | if (target_check_scsi2_reservation_conflict(cmd, &ret)) | 264 | if (target_check_scsi2_reservation_conflict(cmd, &ret)) |
| 260 | return ret; | 265 | goto out; |
| 261 | 266 | ||
| 267 | ret = 0; | ||
| 262 | spin_lock(&dev->dev_reservation_lock); | 268 | spin_lock(&dev->dev_reservation_lock); |
| 263 | if (dev->dev_reserved_node_acl && | 269 | if (dev->dev_reserved_node_acl && |
| 264 | (dev->dev_reserved_node_acl != sess->se_node_acl)) { | 270 | (dev->dev_reserved_node_acl != sess->se_node_acl)) { |
| @@ -271,8 +277,8 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
| 271 | " from %s \n", cmd->se_lun->unpacked_lun, | 277 | " from %s \n", cmd->se_lun->unpacked_lun, |
| 272 | cmd->se_deve->mapped_lun, | 278 | cmd->se_deve->mapped_lun, |
| 273 | sess->se_node_acl->initiatorname); | 279 | sess->se_node_acl->initiatorname); |
| 274 | spin_unlock(&dev->dev_reservation_lock); | 280 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; |
| 275 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 281 | goto out_unlock; |
| 276 | } | 282 | } |
| 277 | 283 | ||
| 278 | dev->dev_reserved_node_acl = sess->se_node_acl; | 284 | dev->dev_reserved_node_acl = sess->se_node_acl; |
| @@ -285,9 +291,15 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
| 285 | " for %s\n", tpg->se_tpg_tfo->get_fabric_name(), | 291 | " for %s\n", tpg->se_tpg_tfo->get_fabric_name(), |
| 286 | cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, | 292 | cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, |
| 287 | sess->se_node_acl->initiatorname); | 293 | sess->se_node_acl->initiatorname); |
| 288 | spin_unlock(&dev->dev_reservation_lock); | ||
| 289 | 294 | ||
| 290 | return 0; | 295 | out_unlock: |
| 296 | spin_unlock(&dev->dev_reservation_lock); | ||
| 297 | out: | ||
| 298 | if (!ret) { | ||
| 299 | task->task_scsi_status = GOOD; | ||
| 300 | transport_complete_task(task, 1); | ||
| 301 | } | ||
| 302 | return ret; | ||
| 291 | } | 303 | } |
| 292 | 304 | ||
| 293 | 305 | ||
| @@ -3744,6 +3756,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
| 3744 | u64 res_key, sa_res_key; | 3756 | u64 res_key, sa_res_key; |
| 3745 | int sa, scope, type, aptpl; | 3757 | int sa, scope, type, aptpl; |
| 3746 | int spec_i_pt = 0, all_tg_pt = 0, unreg = 0; | 3758 | int spec_i_pt = 0, all_tg_pt = 0, unreg = 0; |
| 3759 | int ret; | ||
| 3747 | 3760 | ||
| 3748 | /* | 3761 | /* |
| 3749 | * Following spc2r20 5.5.1 Reservations overview: | 3762 | * Following spc2r20 5.5.1 Reservations overview: |
| @@ -3758,7 +3771,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
| 3758 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" | 3771 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" |
| 3759 | " SPC-2 reservation is held, returning" | 3772 | " SPC-2 reservation is held, returning" |
| 3760 | " RESERVATION_CONFLICT\n"); | 3773 | " RESERVATION_CONFLICT\n"); |
| 3761 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 3774 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; |
| 3775 | goto out; | ||
| 3762 | } | 3776 | } |
| 3763 | 3777 | ||
| 3764 | /* | 3778 | /* |
| @@ -3771,7 +3785,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
| 3771 | if (cmd->data_length < 24) { | 3785 | if (cmd->data_length < 24) { |
| 3772 | pr_warn("SPC-PR: Received PR OUT parameter list" | 3786 | pr_warn("SPC-PR: Received PR OUT parameter list" |
| 3773 | " length too small: %u\n", cmd->data_length); | 3787 | " length too small: %u\n", cmd->data_length); |
| 3774 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3788 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; |
| 3789 | goto out; | ||
| 3775 | } | 3790 | } |
| 3776 | /* | 3791 | /* |
| 3777 | * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB) | 3792 | * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB) |
| @@ -3804,8 +3819,11 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
| 3804 | /* | 3819 | /* |
| 3805 | * SPEC_I_PT=1 is only valid for Service action: REGISTER | 3820 | * SPEC_I_PT=1 is only valid for Service action: REGISTER |
| 3806 | */ | 3821 | */ |
| 3807 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) | 3822 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) { |
| 3808 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3823 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; |
| 3824 | goto out; | ||
| 3825 | } | ||
| 3826 | |||
| 3809 | /* | 3827 | /* |
| 3810 | * From spc4r17 section 6.14: | 3828 | * From spc4r17 section 6.14: |
| 3811 | * | 3829 | * |
| @@ -3819,7 +3837,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
| 3819 | (cmd->data_length != 24)) { | 3837 | (cmd->data_length != 24)) { |
| 3820 | pr_warn("SPC-PR: Received PR OUT illegal parameter" | 3838 | pr_warn("SPC-PR: Received PR OUT illegal parameter" |
| 3821 | " list length: %u\n", cmd->data_length); | 3839 | " list length: %u\n", cmd->data_length); |
| 3822 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3840 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; |
| 3841 | goto out; | ||
| 3823 | } | 3842 | } |
| 3824 | /* | 3843 | /* |
| 3825 | * (core_scsi3_emulate_pro_* function parameters | 3844 | * (core_scsi3_emulate_pro_* function parameters |
| @@ -3828,35 +3847,47 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
| 3828 | */ | 3847 | */ |
| 3829 | switch (sa) { | 3848 | switch (sa) { |
| 3830 | case PRO_REGISTER: | 3849 | case PRO_REGISTER: |
| 3831 | return core_scsi3_emulate_pro_register(cmd, | 3850 | ret = core_scsi3_emulate_pro_register(cmd, |
| 3832 | res_key, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 0); | 3851 | res_key, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 0); |
| 3852 | break; | ||
| 3833 | case PRO_RESERVE: | 3853 | case PRO_RESERVE: |
| 3834 | return core_scsi3_emulate_pro_reserve(cmd, | 3854 | ret = core_scsi3_emulate_pro_reserve(cmd, type, scope, res_key); |
| 3835 | type, scope, res_key); | 3855 | break; |
| 3836 | case PRO_RELEASE: | 3856 | case PRO_RELEASE: |
| 3837 | return core_scsi3_emulate_pro_release(cmd, | 3857 | ret = core_scsi3_emulate_pro_release(cmd, type, scope, res_key); |
| 3838 | type, scope, res_key); | 3858 | break; |
| 3839 | case PRO_CLEAR: | 3859 | case PRO_CLEAR: |
| 3840 | return core_scsi3_emulate_pro_clear(cmd, res_key); | 3860 | ret = core_scsi3_emulate_pro_clear(cmd, res_key); |
| 3861 | break; | ||
| 3841 | case PRO_PREEMPT: | 3862 | case PRO_PREEMPT: |
| 3842 | return core_scsi3_emulate_pro_preempt(cmd, type, scope, | 3863 | ret = core_scsi3_emulate_pro_preempt(cmd, type, scope, |
| 3843 | res_key, sa_res_key, 0); | 3864 | res_key, sa_res_key, 0); |
| 3865 | break; | ||
| 3844 | case PRO_PREEMPT_AND_ABORT: | 3866 | case PRO_PREEMPT_AND_ABORT: |
| 3845 | return core_scsi3_emulate_pro_preempt(cmd, type, scope, | 3867 | ret = core_scsi3_emulate_pro_preempt(cmd, type, scope, |
| 3846 | res_key, sa_res_key, 1); | 3868 | res_key, sa_res_key, 1); |
| 3869 | break; | ||
| 3847 | case PRO_REGISTER_AND_IGNORE_EXISTING_KEY: | 3870 | case PRO_REGISTER_AND_IGNORE_EXISTING_KEY: |
| 3848 | return core_scsi3_emulate_pro_register(cmd, | 3871 | ret = core_scsi3_emulate_pro_register(cmd, |
| 3849 | 0, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 1); | 3872 | 0, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 1); |
| 3873 | break; | ||
| 3850 | case PRO_REGISTER_AND_MOVE: | 3874 | case PRO_REGISTER_AND_MOVE: |
| 3851 | return core_scsi3_emulate_pro_register_and_move(cmd, res_key, | 3875 | ret = core_scsi3_emulate_pro_register_and_move(cmd, res_key, |
| 3852 | sa_res_key, aptpl, unreg); | 3876 | sa_res_key, aptpl, unreg); |
| 3877 | break; | ||
| 3853 | default: | 3878 | default: |
| 3854 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" | 3879 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" |
| 3855 | " action: 0x%02x\n", cdb[1] & 0x1f); | 3880 | " action: 0x%02x\n", cdb[1] & 0x1f); |
| 3856 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 3881 | ret = PYX_TRANSPORT_INVALID_CDB_FIELD; |
| 3882 | break; | ||
| 3857 | } | 3883 | } |
| 3858 | 3884 | ||
| 3859 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 3885 | out: |
| 3886 | if (!ret) { | ||
| 3887 | task->task_scsi_status = GOOD; | ||
| 3888 | transport_complete_task(task, 1); | ||
| 3889 | } | ||
| 3890 | return ret; | ||
| 3860 | } | 3891 | } |
| 3861 | 3892 | ||
| 3862 | /* | 3893 | /* |
| @@ -4209,6 +4240,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | |||
| 4209 | int target_scsi3_emulate_pr_in(struct se_task *task) | 4240 | int target_scsi3_emulate_pr_in(struct se_task *task) |
| 4210 | { | 4241 | { |
| 4211 | struct se_cmd *cmd = task->task_se_cmd; | 4242 | struct se_cmd *cmd = task->task_se_cmd; |
| 4243 | int ret; | ||
| 4212 | 4244 | ||
| 4213 | /* | 4245 | /* |
| 4214 | * Following spc2r20 5.5.1 Reservations overview: | 4246 | * Following spc2r20 5.5.1 Reservations overview: |
| @@ -4228,18 +4260,29 @@ int target_scsi3_emulate_pr_in(struct se_task *task) | |||
| 4228 | 4260 | ||
| 4229 | switch (cmd->t_task_cdb[1] & 0x1f) { | 4261 | switch (cmd->t_task_cdb[1] & 0x1f) { |
| 4230 | case PRI_READ_KEYS: | 4262 | case PRI_READ_KEYS: |
| 4231 | return core_scsi3_pri_read_keys(cmd); | 4263 | ret = core_scsi3_pri_read_keys(cmd); |
| 4264 | break; | ||
| 4232 | case PRI_READ_RESERVATION: | 4265 | case PRI_READ_RESERVATION: |
| 4233 | return core_scsi3_pri_read_reservation(cmd); | 4266 | ret = core_scsi3_pri_read_reservation(cmd); |
| 4267 | break; | ||
| 4234 | case PRI_REPORT_CAPABILITIES: | 4268 | case PRI_REPORT_CAPABILITIES: |
| 4235 | return core_scsi3_pri_report_capabilities(cmd); | 4269 | ret = core_scsi3_pri_report_capabilities(cmd); |
| 4270 | break; | ||
| 4236 | case PRI_READ_FULL_STATUS: | 4271 | case PRI_READ_FULL_STATUS: |
| 4237 | return core_scsi3_pri_read_full_status(cmd); | 4272 | ret = core_scsi3_pri_read_full_status(cmd); |
| 4273 | break; | ||
| 4238 | default: | 4274 | default: |
| 4239 | pr_err("Unknown PERSISTENT_RESERVE_IN service" | 4275 | pr_err("Unknown PERSISTENT_RESERVE_IN service" |
| 4240 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); | 4276 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); |
| 4241 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 4277 | ret = PYX_TRANSPORT_INVALID_CDB_FIELD; |
| 4278 | break; | ||
| 4279 | } | ||
| 4280 | |||
| 4281 | if (!ret) { | ||
| 4282 | task->task_scsi_status = GOOD; | ||
| 4283 | transport_complete_task(task, 1); | ||
| 4242 | } | 4284 | } |
| 4285 | return ret; | ||
| 4243 | } | 4286 | } |
| 4244 | 4287 | ||
| 4245 | static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type) | 4288 | static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type) |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 3ad8db2d3ad3..74015793c03a 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
| @@ -2162,28 +2162,6 @@ check_depth: | |||
| 2162 | */ | 2162 | */ |
| 2163 | if (cmd->execute_task) { | 2163 | if (cmd->execute_task) { |
| 2164 | error = cmd->execute_task(task); | 2164 | error = cmd->execute_task(task); |
| 2165 | if (error != 0) { | ||
| 2166 | cmd->transport_error_status = error; | ||
| 2167 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
| 2168 | task->task_flags &= ~TF_ACTIVE; | ||
| 2169 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
| 2170 | atomic_set(&cmd->t_transport_sent, 0); | ||
| 2171 | transport_stop_tasks_for_cmd(cmd); | ||
| 2172 | atomic_inc(&dev->depth_left); | ||
| 2173 | transport_generic_request_failure(cmd, 0, 1); | ||
| 2174 | goto check_depth; | ||
| 2175 | } | ||
| 2176 | /* | ||
| 2177 | * Handle the successful completion for execute_task() | ||
| 2178 | * for synchronous operation, following SCF_EMULATE_CDB_ASYNC | ||
| 2179 | * Otherwise the caller is expected to complete the task with | ||
| 2180 | * proper status. | ||
| 2181 | */ | ||
| 2182 | if (!(cmd->se_cmd_flags & SCF_EMULATE_CDB_ASYNC)) { | ||
| 2183 | cmd->scsi_status = SAM_STAT_GOOD; | ||
| 2184 | task->task_scsi_status = GOOD; | ||
| 2185 | transport_complete_task(task, 1); | ||
| 2186 | } | ||
| 2187 | } else { | 2165 | } else { |
| 2188 | /* | 2166 | /* |
| 2189 | * Currently for all virtual TCM plugins including IBLOCK, FILEIO and | 2167 | * Currently for all virtual TCM plugins including IBLOCK, FILEIO and |
| @@ -2200,17 +2178,17 @@ check_depth: | |||
| 2200 | error = transport_emulate_control_cdb(task); | 2178 | error = transport_emulate_control_cdb(task); |
| 2201 | else | 2179 | else |
| 2202 | error = dev->transport->do_task(task); | 2180 | error = dev->transport->do_task(task); |
| 2181 | } | ||
| 2203 | 2182 | ||
| 2204 | if (error != 0) { | 2183 | if (error != 0) { |
| 2205 | cmd->transport_error_status = error; | 2184 | cmd->transport_error_status = error; |
| 2206 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 2185 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
| 2207 | task->task_flags &= ~TF_ACTIVE; | 2186 | task->task_flags &= ~TF_ACTIVE; |
| 2208 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 2187 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
| 2209 | atomic_set(&cmd->t_transport_sent, 0); | 2188 | atomic_set(&cmd->t_transport_sent, 0); |
| 2210 | transport_stop_tasks_for_cmd(cmd); | 2189 | transport_stop_tasks_for_cmd(cmd); |
| 2211 | atomic_inc(&dev->depth_left); | 2190 | atomic_inc(&dev->depth_left); |
| 2212 | transport_generic_request_failure(cmd, 0, 1); | 2191 | transport_generic_request_failure(cmd, 0, 1); |
| 2213 | } | ||
| 2214 | } | 2192 | } |
| 2215 | 2193 | ||
| 2216 | goto check_depth; | 2194 | goto check_depth; |
| @@ -3002,11 +2980,6 @@ static int transport_generic_cmd_sequencer( | |||
| 3002 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) | 2980 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
| 3003 | break; | 2981 | break; |
| 3004 | /* | 2982 | /* |
| 3005 | * Set SCF_EMULATE_CDB_ASYNC to ensure asynchronous operation | ||
| 3006 | * for SYNCHRONIZE_CACHE* Immed=1 case in __transport_execute_tasks() | ||
| 3007 | */ | ||
| 3008 | cmd->se_cmd_flags |= SCF_EMULATE_CDB_ASYNC; | ||
| 3009 | /* | ||
| 3010 | * Check to ensure that LBA + Range does not exceed past end of | 2983 | * Check to ensure that LBA + Range does not exceed past end of |
| 3011 | * device for IBLOCK and FILEIO ->do_sync_cache() backend calls | 2984 | * device for IBLOCK and FILEIO ->do_sync_cache() backend calls |
| 3012 | */ | 2985 | */ |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 14c1a71a36eb..7f5fed3c89e1 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
| @@ -114,7 +114,6 @@ enum se_cmd_flags_table { | |||
| 114 | SCF_DELAYED_CMD_FROM_SAM_ATTR = 0x00080000, | 114 | SCF_DELAYED_CMD_FROM_SAM_ATTR = 0x00080000, |
| 115 | SCF_UNUSED = 0x00100000, | 115 | SCF_UNUSED = 0x00100000, |
| 116 | SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00400000, | 116 | SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00400000, |
| 117 | SCF_EMULATE_CDB_ASYNC = 0x01000000, | ||
| 118 | }; | 117 | }; |
| 119 | 118 | ||
| 120 | /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */ | 119 | /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */ |
