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.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index aa2d67997235..3df1c9b8ae6b 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -174,6 +174,24 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
174 sgl_bidi = sdb->table.sgl; 174 sgl_bidi = sdb->table.sgl;
175 sgl_bidi_count = sdb->table.nents; 175 sgl_bidi_count = sdb->table.nents;
176 } 176 }
177 /*
178 * Because some userspace code via scsi-generic do not memset their
179 * associated read buffers, go ahead and do that here for type
180 * SCF_SCSI_CONTROL_SG_IO_CDB. Also note that this is currently
181 * guaranteed to be a single SGL for SCF_SCSI_CONTROL_SG_IO_CDB
182 * by target core in transport_generic_allocate_tasks() ->
183 * transport_generic_cmd_sequencer().
184 */
185 if (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB &&
186 se_cmd->data_direction == DMA_FROM_DEVICE) {
187 struct scatterlist *sg = scsi_sglist(sc);
188 unsigned char *buf = kmap(sg_page(sg)) + sg->offset;
189
190 if (buf != NULL) {
191 memset(buf, 0, sg->length);
192 kunmap(sg_page(sg));
193 }
194 }
177 195
178 /* Tell the core about our preallocated memory */ 196 /* Tell the core about our preallocated memory */
179 ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), 197 ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
@@ -187,7 +205,7 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
187/* 205/*
188 * Called from struct target_core_fabric_ops->check_stop_free() 206 * Called from struct target_core_fabric_ops->check_stop_free()
189 */ 207 */
190static void tcm_loop_check_stop_free(struct se_cmd *se_cmd) 208static int tcm_loop_check_stop_free(struct se_cmd *se_cmd)
191{ 209{
192 /* 210 /*
193 * Do not release struct se_cmd's containing a valid TMR 211 * Do not release struct se_cmd's containing a valid TMR
@@ -195,12 +213,13 @@ static void tcm_loop_check_stop_free(struct se_cmd *se_cmd)
195 * with transport_generic_free_cmd(). 213 * with transport_generic_free_cmd().
196 */ 214 */
197 if (se_cmd->se_tmr_req) 215 if (se_cmd->se_tmr_req)
198 return; 216 return 0;
199 /* 217 /*
200 * Release the struct se_cmd, which will make a callback to release 218 * Release the struct se_cmd, which will make a callback to release
201 * struct tcm_loop_cmd * in tcm_loop_deallocate_core_cmd() 219 * struct tcm_loop_cmd * in tcm_loop_deallocate_core_cmd()
202 */ 220 */
203 transport_generic_free_cmd(se_cmd, 0, 0); 221 transport_generic_free_cmd(se_cmd, 0);
222 return 1;
204} 223}
205 224
206static void tcm_loop_release_cmd(struct se_cmd *se_cmd) 225static void tcm_loop_release_cmd(struct se_cmd *se_cmd)
@@ -290,6 +309,15 @@ static int tcm_loop_queuecommand(
290 */ 309 */
291 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); 310 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
292 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; 311 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
312 /*
313 * Ensure that this tl_tpg reference from the incoming sc->device->id
314 * has already been configured via tcm_loop_make_naa_tpg().
315 */
316 if (!tl_tpg->tl_hba) {
317 set_host_byte(sc, DID_NO_CONNECT);
318 sc->scsi_done(sc);
319 return 0;
320 }
293 se_tpg = &tl_tpg->tl_se_tpg; 321 se_tpg = &tl_tpg->tl_se_tpg;
294 /* 322 /*
295 * Determine the SAM Task Attribute and allocate tl_cmd and 323 * Determine the SAM Task Attribute and allocate tl_cmd and
@@ -366,7 +394,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
366 * Allocate the LUN_RESET TMR 394 * Allocate the LUN_RESET TMR
367 */ 395 */
368 se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, tl_tmr, 396 se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, tl_tmr,
369 TMR_LUN_RESET); 397 TMR_LUN_RESET, GFP_KERNEL);
370 if (IS_ERR(se_cmd->se_tmr_req)) 398 if (IS_ERR(se_cmd->se_tmr_req))
371 goto release; 399 goto release;
372 /* 400 /*
@@ -388,7 +416,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
388 SUCCESS : FAILED; 416 SUCCESS : FAILED;
389release: 417release:
390 if (se_cmd) 418 if (se_cmd)
391 transport_generic_free_cmd(se_cmd, 1, 0); 419 transport_generic_free_cmd(se_cmd, 1);
392 else 420 else
393 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); 421 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
394 kfree(tl_tmr); 422 kfree(tl_tmr);
@@ -1245,6 +1273,9 @@ void tcm_loop_drop_naa_tpg(
1245 */ 1273 */
1246 core_tpg_deregister(se_tpg); 1274 core_tpg_deregister(se_tpg);
1247 1275
1276 tl_tpg->tl_hba = NULL;
1277 tl_tpg->tl_tpgt = 0;
1278
1248 pr_debug("TCM_Loop_ConfigFS: Deallocated Emulated %s" 1279 pr_debug("TCM_Loop_ConfigFS: Deallocated Emulated %s"
1249 " Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba), 1280 " Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba),
1250 config_item_name(&wwn->wwn_group.cg_item), tpgt); 1281 config_item_name(&wwn->wwn_group.cg_item), tpgt);