aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/loopback/tcm_loop.c83
1 files changed, 50 insertions, 33 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index a00ad27940b7..783675f7cdab 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -245,41 +245,21 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc)
245 * Called from SCSI EH process context to issue a LUN_RESET TMR 245 * Called from SCSI EH process context to issue a LUN_RESET TMR
246 * to struct scsi_device 246 * to struct scsi_device
247 */ 247 */
248static int tcm_loop_device_reset(struct scsi_cmnd *sc) 248static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
249 struct tcm_loop_nexus *tl_nexus,
250 int lun, enum tcm_tmreq_table tmr)
249{ 251{
250 struct se_cmd *se_cmd = NULL; 252 struct se_cmd *se_cmd = NULL;
251 struct se_portal_group *se_tpg;
252 struct se_session *se_sess; 253 struct se_session *se_sess;
254 struct se_portal_group *se_tpg;
253 struct tcm_loop_cmd *tl_cmd = NULL; 255 struct tcm_loop_cmd *tl_cmd = NULL;
254 struct tcm_loop_hba *tl_hba;
255 struct tcm_loop_nexus *tl_nexus;
256 struct tcm_loop_tmr *tl_tmr = NULL; 256 struct tcm_loop_tmr *tl_tmr = NULL;
257 struct tcm_loop_tpg *tl_tpg; 257 int ret = TMR_FUNCTION_FAILED, rc;
258 int ret = FAILED, rc;
259 /*
260 * Locate the tcm_loop_hba_t pointer
261 */
262 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
263 /*
264 * Locate the tl_nexus and se_sess pointers
265 */
266 tl_nexus = tl_hba->tl_nexus;
267 if (!tl_nexus) {
268 pr_err("Unable to perform device reset without"
269 " active I_T Nexus\n");
270 return FAILED;
271 }
272 se_sess = tl_nexus->se_sess;
273 /*
274 * Locate the tl_tpg and se_tpg pointers from TargetID in sc->device->id
275 */
276 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
277 se_tpg = &tl_tpg->tl_se_tpg;
278 258
279 tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL); 259 tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL);
280 if (!tl_cmd) { 260 if (!tl_cmd) {
281 pr_err("Unable to allocate memory for tl_cmd\n"); 261 pr_err("Unable to allocate memory for tl_cmd\n");
282 return FAILED; 262 return ret;
283 } 263 }
284 264
285 tl_tmr = kzalloc(sizeof(struct tcm_loop_tmr), GFP_KERNEL); 265 tl_tmr = kzalloc(sizeof(struct tcm_loop_tmr), GFP_KERNEL);
@@ -290,6 +270,8 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
290 init_waitqueue_head(&tl_tmr->tl_tmr_wait); 270 init_waitqueue_head(&tl_tmr->tl_tmr_wait);
291 271
292 se_cmd = &tl_cmd->tl_se_cmd; 272 se_cmd = &tl_cmd->tl_se_cmd;
273 se_tpg = &tl_tpg->tl_se_tpg;
274 se_sess = tl_nexus->se_sess;
293 /* 275 /*
294 * Initialize struct se_cmd descriptor from target_core_mod infrastructure 276 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
295 */ 277 */
@@ -297,17 +279,20 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
297 DMA_NONE, MSG_SIMPLE_TAG, 279 DMA_NONE, MSG_SIMPLE_TAG,
298 &tl_cmd->tl_sense_buf[0]); 280 &tl_cmd->tl_sense_buf[0]);
299 281
300 rc = core_tmr_alloc_req(se_cmd, tl_tmr, TMR_LUN_RESET, GFP_KERNEL); 282 rc = core_tmr_alloc_req(se_cmd, tl_tmr, tmr, GFP_KERNEL);
301 if (rc < 0) 283 if (rc < 0)
302 goto release; 284 goto release;
285
303 /* 286 /*
304 * Locate the underlying TCM struct se_lun from sc->device->lun 287 * Locate the underlying TCM struct se_lun
305 */ 288 */
306 if (transport_lookup_tmr_lun(se_cmd, sc->device->lun) < 0) 289 if (transport_lookup_tmr_lun(se_cmd, lun) < 0) {
290 ret = TMR_LUN_DOES_NOT_EXIST;
307 goto release; 291 goto release;
292 }
308 /* 293 /*
309 * Queue the TMR to TCM Core and sleep waiting for tcm_loop_queue_tm_rsp() 294 * Queue the TMR to TCM Core and sleep waiting for
310 * to wake us up. 295 * tcm_loop_queue_tm_rsp() to wake us up.
311 */ 296 */
312 transport_generic_handle_tmr(se_cmd); 297 transport_generic_handle_tmr(se_cmd);
313 wait_event(tl_tmr->tl_tmr_wait, atomic_read(&tl_tmr->tmr_complete)); 298 wait_event(tl_tmr->tl_tmr_wait, atomic_read(&tl_tmr->tmr_complete));
@@ -315,8 +300,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
315 * The TMR LUN_RESET has completed, check the response status and 300 * The TMR LUN_RESET has completed, check the response status and
316 * then release allocations. 301 * then release allocations.
317 */ 302 */
318 ret = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ? 303 ret = se_cmd->se_tmr_req->response;
319 SUCCESS : FAILED;
320release: 304release:
321 if (se_cmd) 305 if (se_cmd)
322 transport_generic_free_cmd(se_cmd, 1); 306 transport_generic_free_cmd(se_cmd, 1);
@@ -326,6 +310,39 @@ release:
326 return ret; 310 return ret;
327} 311}
328 312
313/*
314 * Called from SCSI EH process context to issue a LUN_RESET TMR
315 * to struct scsi_device
316 */
317static int tcm_loop_device_reset(struct scsi_cmnd *sc)
318{
319 struct tcm_loop_hba *tl_hba;
320 struct tcm_loop_nexus *tl_nexus;
321 struct tcm_loop_tpg *tl_tpg;
322 int ret = FAILED;
323
324 /*
325 * Locate the tcm_loop_hba_t pointer
326 */
327 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
328 /*
329 * Locate the tl_nexus and se_sess pointers
330 */
331 tl_nexus = tl_hba->tl_nexus;
332 if (!tl_nexus) {
333 pr_err("Unable to perform device reset without"
334 " active I_T Nexus\n");
335 return FAILED;
336 }
337 /*
338 * Locate the tl_tpg pointer from TargetID in sc->device->id
339 */
340 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
341 ret = tcm_loop_issue_tmr(tl_tpg, tl_nexus,
342 sc->device->lun, TMR_LUN_RESET);
343 return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
344}
345
329static int tcm_loop_slave_alloc(struct scsi_device *sd) 346static int tcm_loop_slave_alloc(struct scsi_device *sd)
330{ 347{
331 set_bit(QUEUE_FLAG_BIDI, &sd->request_queue->queue_flags); 348 set_bit(QUEUE_FLAG_BIDI, &sd->request_queue->queue_flags);