@@ -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.
*/
@@ -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 *);
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@synopsys.com> --- drivers/target/target_core_transport.c | 33 ++++++++++++++++++++++++++ include/target/target_core_fabric.h | 3 +++ 2 files changed, 36 insertions(+)