diff options
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_transport.c | 49 |
1 files changed, 21 insertions, 28 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index a63f19bf47f8..3cb0aa798d73 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1592,6 +1592,27 @@ int transport_handle_cdb_direct( */ core_alua_check_nonop_delay(cmd); + if (cmd->t_data_nents != 0) { + /* + * This is primarily a hack for udev and tcm loop which sends + * INQUIRYs with a single page and expects the data to be + * cleared. + */ + if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && + cmd->data_direction == DMA_FROM_DEVICE) { + struct scatterlist *sgl = cmd->t_data_sg; + unsigned char *buf = NULL; + + BUG_ON(!sgl); + + buf = kmap_local_page(sg_page(sgl)); + if (buf) { + memset(buf + sgl->offset, 0, sgl->length); + kunmap_local(buf); + } + } + } + if (!cmd->se_lun) { dump_stack(); pr_err("cmd->se_lun is NULL\n"); @@ -1795,34 +1816,6 @@ EXPORT_SYMBOL_GPL(target_submit_prep); */ void target_submit(struct se_cmd *se_cmd) { - struct scatterlist *sgl = se_cmd->t_data_sg; - unsigned char *buf = NULL; - - might_sleep(); - - if (se_cmd->t_data_nents != 0) { - BUG_ON(!sgl); - /* - * A work-around for tcm_loop as some userspace code via - * scsi-generic do not memset their associated read buffers, - * so go ahead and do that here for type non-data CDBs. Also - * note that this is currently guaranteed to be a single SGL - * for this case by target core in target_setup_cmd_from_cdb() - * -> transport_generic_cmd_sequencer(). - */ - if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && - se_cmd->data_direction == DMA_FROM_DEVICE) { - if (sgl) - buf = kmap(sg_page(sgl)) + sgl->offset; - - if (buf) { - memset(buf, 0, sgl->length); - kunmap(sg_page(sgl)); - } - } - - } - transport_handle_cdb_direct(se_cmd); } EXPORT_SYMBOL_GPL(target_submit); |