aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/loopback/tcm_loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/target/loopback/tcm_loop.c')
-rw-r--r--drivers/target/loopback/tcm_loop.c77
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);
51 */ 51 */
52static int tcm_loop_check_stop_free(struct se_cmd *se_cmd) 52static int tcm_loop_check_stop_free(struct se_cmd *se_cmd)
53{ 53{
54 /* 54 return transport_generic_free_cmd(se_cmd, 0);
55 * Do not release struct se_cmd's containing a valid TMR
56 * pointer. These will be released directly in tcm_loop_device_reset()
57 * with transport_generic_free_cmd().
58 */
59 if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
60 return 0;
61 /*
62 * Release the struct se_cmd, which will make a callback to release
63 * struct tcm_loop_cmd * in tcm_loop_deallocate_core_cmd()
64 */
65 transport_generic_free_cmd(se_cmd, 0);
66 return 1;
67} 55}
68 56
69static void tcm_loop_release_cmd(struct se_cmd *se_cmd) 57static 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,
218{ 206{
219 struct se_cmd *se_cmd = NULL; 207 struct se_cmd *se_cmd = NULL;
220 struct se_session *se_sess; 208 struct se_session *se_sess;
221 struct se_portal_group *se_tpg;
222 struct tcm_loop_nexus *tl_nexus; 209 struct tcm_loop_nexus *tl_nexus;
223 struct tcm_loop_cmd *tl_cmd = NULL; 210 struct tcm_loop_cmd *tl_cmd = NULL;
224 struct tcm_loop_tmr *tl_tmr = NULL;
225 int ret = TMR_FUNCTION_FAILED, rc; 211 int ret = TMR_FUNCTION_FAILED, rc;
226 212
227 /* 213 /*
@@ -240,55 +226,29 @@ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
240 return ret; 226 return ret;
241 } 227 }
242 228
243 tl_tmr = kzalloc(sizeof(struct tcm_loop_tmr), GFP_KERNEL); 229 init_completion(&tl_cmd->tmr_done);
244 if (!tl_tmr) {
245 pr_err("Unable to allocate memory for tl_tmr\n");
246 goto release;
247 }
248 init_waitqueue_head(&tl_tmr->tl_tmr_wait);
249 230
250 se_cmd = &tl_cmd->tl_se_cmd; 231 se_cmd = &tl_cmd->tl_se_cmd;
251 se_tpg = &tl_tpg->tl_se_tpg;
252 se_sess = tl_tpg->tl_nexus->se_sess; 232 se_sess = tl_tpg->tl_nexus->se_sess;
253 /*
254 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
255 */
256 transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, 0,
257 DMA_NONE, TCM_SIMPLE_TAG,
258 &tl_cmd->tl_sense_buf[0]);
259 233
260 rc = core_tmr_alloc_req(se_cmd, tl_tmr, tmr, GFP_KERNEL); 234 rc = target_submit_tmr(se_cmd, se_sess, tl_cmd->tl_sense_buf, lun,
235 NULL, tmr, GFP_KERNEL, task,
236 TARGET_SCF_ACK_KREF);
261 if (rc < 0) 237 if (rc < 0)
262 goto release; 238 goto release;
239 wait_for_completion(&tl_cmd->tmr_done);
240 ret = se_cmd->se_tmr_req->response;
241 target_put_sess_cmd(se_cmd);
263 242
264 if (tmr == TMR_ABORT_TASK) 243out:
265 se_cmd->se_tmr_req->ref_task_tag = task; 244 return ret;
266 245
267 /*
268 * Locate the underlying TCM struct se_lun
269 */
270 if (transport_lookup_tmr_lun(se_cmd, lun) < 0) {
271 ret = TMR_LUN_DOES_NOT_EXIST;
272 goto release;
273 }
274 /*
275 * Queue the TMR to TCM Core and sleep waiting for
276 * tcm_loop_queue_tm_rsp() to wake us up.
277 */
278 transport_generic_handle_tmr(se_cmd);
279 wait_event(tl_tmr->tl_tmr_wait, atomic_read(&tl_tmr->tmr_complete));
280 /*
281 * The TMR LUN_RESET has completed, check the response status and
282 * then release allocations.
283 */
284 ret = se_cmd->se_tmr_req->response;
285release: 246release:
286 if (se_cmd) 247 if (se_cmd)
287 transport_generic_free_cmd(se_cmd, 1); 248 transport_generic_free_cmd(se_cmd, 0);
288 else 249 else
289 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); 250 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
290 kfree(tl_tmr); 251 goto out;
291 return ret;
292} 252}
293 253
294static int tcm_loop_abort_task(struct scsi_cmnd *sc) 254static int tcm_loop_abort_task(struct scsi_cmnd *sc)
@@ -669,14 +629,11 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd)
669 629
670static void tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd) 630static void tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd)
671{ 631{
672 struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; 632 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
673 struct tcm_loop_tmr *tl_tmr = se_tmr->fabric_tmr_ptr; 633 struct tcm_loop_cmd, tl_se_cmd);
674 /* 634
675 * The SCSI EH thread will be sleeping on se_tmr->tl_tmr_wait, go ahead 635 /* Wake up tcm_loop_issue_tmr(). */
676 * and wake up the wait_queue_head_t in tcm_loop_device_reset() 636 complete(&tl_cmd->tmr_done);
677 */
678 atomic_set(&tl_tmr->tmr_complete, 1);
679 wake_up(&tl_tmr->tl_tmr_wait);
680} 637}
681 638
682static void tcm_loop_aborted_task(struct se_cmd *se_cmd) 639static void tcm_loop_aborted_task(struct se_cmd *se_cmd)