diff options
author | Hannes Reinecke <hare@suse.de> | 2013-10-16 03:12:54 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-10-16 18:41:49 -0400 |
commit | a314d7003ccd4f4886d1280ff4f6c00217fc9ae3 (patch) | |
tree | 9c774ff0636ad0c7bf021dabdd0d3675a4b92e83 /drivers/target | |
parent | fb2b2844743bc3d84ce1033167210e5fe3963455 (diff) |
tcm_loop: separate out tcm_loop_issue_tmr
No functional change.
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/loopback/tcm_loop.c | 83 |
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 | */ |
248 | static int tcm_loop_device_reset(struct scsi_cmnd *sc) | 248 | static 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; | ||
320 | release: | 304 | release: |
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 | */ | ||
317 | static 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 | |||
329 | static int tcm_loop_slave_alloc(struct scsi_device *sd) | 346 | static 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); |