diff options
Diffstat (limited to 'drivers/target/loopback/tcm_loop.c')
-rw-r--r-- | drivers/target/loopback/tcm_loop.c | 77 |
1 files changed, 17 insertions, 60 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 5091b31b3e56..b6a913e38b30 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -51,19 +51,7 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd); */ static int tcm_loop_check_stop_free(struct se_cmd *se_cmd) { - /* - * Do not release struct se_cmd's containing a valid TMR - * pointer. These will be released directly in tcm_loop_device_reset() - * with transport_generic_free_cmd(). - */ - if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) - return 0; - /* - * Release the struct se_cmd, which will make a callback to release - * struct tcm_loop_cmd * in tcm_loop_deallocate_core_cmd() - */ - transport_generic_free_cmd(se_cmd, 0); - return 1; + return transport_generic_free_cmd(se_cmd, 0); } static void tcm_loop_release_cmd(struct se_cmd *se_cmd) @@ -218,10 +206,8 @@ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg, { struct se_cmd *se_cmd = NULL; struct se_session *se_sess; - struct se_portal_group *se_tpg; struct tcm_loop_nexus *tl_nexus; struct tcm_loop_cmd *tl_cmd = NULL; - struct tcm_loop_tmr *tl_tmr = NULL; int ret = TMR_FUNCTION_FAILED, rc; /* @@ -240,55 +226,29 @@ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg, return ret; } - tl_tmr = kzalloc(sizeof(struct tcm_loop_tmr), GFP_KERNEL); - if (!tl_tmr) { - pr_err("Unable to allocate memory for tl_tmr\n"); - goto release; - } - init_waitqueue_head(&tl_tmr->tl_tmr_wait); + init_completion(&tl_cmd->tmr_done); se_cmd = &tl_cmd->tl_se_cmd; - se_tpg = &tl_tpg->tl_se_tpg; se_sess = tl_tpg->tl_nexus->se_sess; - /* - * Initialize struct se_cmd descriptor from target_core_mod infrastructure - */ - transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, 0, - DMA_NONE, TCM_SIMPLE_TAG, - &tl_cmd->tl_sense_buf[0]); - rc = core_tmr_alloc_req(se_cmd, tl_tmr, tmr, GFP_KERNEL); + rc = target_submit_tmr(se_cmd, se_sess, tl_cmd->tl_sense_buf, lun, + NULL, tmr, GFP_KERNEL, task, + TARGET_SCF_ACK_KREF); if (rc < 0) goto release; + wait_for_completion(&tl_cmd->tmr_done); + ret = se_cmd->se_tmr_req->response; + target_put_sess_cmd(se_cmd); - if (tmr == TMR_ABORT_TASK) - se_cmd->se_tmr_req->ref_task_tag = task; +out: + return ret; - /* - * Locate the underlying TCM struct se_lun - */ - if (transport_lookup_tmr_lun(se_cmd, lun) < 0) { - ret = TMR_LUN_DOES_NOT_EXIST; - goto release; - } - /* - * Queue the TMR to TCM Core and sleep waiting for - * tcm_loop_queue_tm_rsp() to wake us up. - */ - transport_generic_handle_tmr(se_cmd); - wait_event(tl_tmr->tl_tmr_wait, atomic_read(&tl_tmr->tmr_complete)); - /* - * The TMR LUN_RESET has completed, check the response status and - * then release allocations. - */ - ret = se_cmd->se_tmr_req->response; release: if (se_cmd) - transport_generic_free_cmd(se_cmd, 1); + transport_generic_free_cmd(se_cmd, 0); else kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); - kfree(tl_tmr); - return ret; + goto out; } static int tcm_loop_abort_task(struct scsi_cmnd *sc) @@ -669,14 +629,11 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd) static void tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd) { - struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; - struct tcm_loop_tmr *tl_tmr = se_tmr->fabric_tmr_ptr; - /* - * The SCSI EH thread will be sleeping on se_tmr->tl_tmr_wait, go ahead - * and wake up the wait_queue_head_t in tcm_loop_device_reset() - */ - atomic_set(&tl_tmr->tmr_complete, 1); - wake_up(&tl_tmr->tl_tmr_wait); + struct tcm_loop_cmd *tl_cmd = container_of(se_cmd, + struct tcm_loop_cmd, tl_se_cmd); + + /* Wake up tcm_loop_issue_tmr(). */ + complete(&tl_cmd->tmr_done); } static void tcm_loop_aborted_task(struct se_cmd *se_cmd) |