Similar to transport_send_check_condition_and_sense(), some error condition and status can only be checked by the user of the target core (such as TMR_OVERLAPPED_TAG_ATTEMPTED). Introduce target_submit_tmr_fail_response() to allow the user to directly provide the fail reason of the TMR command. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@xxxxxxxxxxxx> --- drivers/target/target_core_transport.c | 33 ++++++++++++++++++++++++++ include/target/target_core_fabric.h | 3 +++ 2 files changed, 36 insertions(+) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 930bf8779d87..c899da241b38 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1989,6 +1989,39 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, } EXPORT_SYMBOL(target_submit_tmr); +void target_submit_tmr_fail_response(struct se_cmd *se_cmd, + enum tcm_tmrsp_table rsp, + struct se_session *se_sess, u64 unpacked_lun, + gfp_t gfp, u64 tag, int flags) +{ + struct se_portal_group *se_tpg; + int ret; + + se_tpg = se_sess->se_tpg; + BUG_ON(!se_tpg); + + __target_init_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, + 0, DMA_NONE, TCM_SIMPLE_TAG, NULL, unpacked_lun); + + ret = core_tmr_alloc_req(se_cmd, NULL, TMR_UNKNOWN, gfp); + if (ret < 0) + return; + + se_cmd->se_tmr_req->ref_task_tag = tag; + se_cmd->se_tmr_req->response = rsp; + + /* See target_submit_cmd for commentary */ + ret = target_get_sess_cmd(se_cmd, flags & TARGET_SCF_ACK_KREF); + if (ret) { + core_tmr_release_req(se_cmd->se_tmr_req); + return; + } + + INIT_WORK(&se_cmd->work, target_complete_tmr_failure); + schedule_work(&se_cmd->work); +} +EXPORT_SYMBOL(target_submit_tmr_fail_response); + /* * Handle SAM-esque emulation for generic transport request failures. */ diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 38f0662476d1..73bf6b372926 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -172,6 +172,9 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *sense, u64 unpacked_lun, void *fabric_tmr_ptr, unsigned char tm_type, gfp_t, u64, int); +void target_submit_tmr_fail_response(struct se_cmd *se_cmd, + enum tcm_tmrsp_table rsp, + struct se_session *se_sess, u64 unpacked_lun, gfp_t, u64, int); int transport_handle_cdb_direct(struct se_cmd *); sense_reason_t transport_generic_new_cmd(struct se_cmd *); -- 2.28.0