diff options
| author | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-10-02 02:29:49 -0400 |
|---|---|---|
| committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-10-02 17:16:11 -0400 |
| commit | 8f9f44f8957b262de717a48269a5ceca36c2b504 (patch) | |
| tree | 54281bd040994ec92f25dc140aa29a4647dee5ae /drivers/target/loopback | |
| parent | a026757ff56365b4aa3875c14f1bd5733e0e8bb2 (diff) | |
tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls
This patch converts tcm_loop to use target_submit_cmd_map_sgls() for
I/O submission and mapping of pre-allocated SGL memory from incoming
scsi_cmnd -> se_cmd descriptors.
This includes removing the original open-coded fabric uses of target
core callers to support transport_generic_map_mem_to_cmd() between
target_setup_cmd_from_cdb() and transport_handle_cdb_direct() logic.
(v2: Use renamed target_submit_cmd_map_sgls)
Reported-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/loopback')
| -rw-r--r-- | drivers/target/loopback/tcm_loop.c | 62 |
1 files changed, 8 insertions, 54 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 7a0da1ae0040..2d444b1ccd33 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c | |||
| @@ -166,7 +166,7 @@ static void tcm_loop_submission_work(struct work_struct *work) | |||
| 166 | struct tcm_loop_tpg *tl_tpg; | 166 | struct tcm_loop_tpg *tl_tpg; |
| 167 | struct scatterlist *sgl_bidi = NULL; | 167 | struct scatterlist *sgl_bidi = NULL; |
| 168 | u32 sgl_bidi_count = 0; | 168 | u32 sgl_bidi_count = 0; |
| 169 | int ret; | 169 | int rc; |
| 170 | 170 | ||
| 171 | tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); | 171 | tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); |
| 172 | tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; | 172 | tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; |
| @@ -187,12 +187,6 @@ static void tcm_loop_submission_work(struct work_struct *work) | |||
| 187 | set_host_byte(sc, DID_ERROR); | 187 | set_host_byte(sc, DID_ERROR); |
| 188 | goto out_done; | 188 | goto out_done; |
| 189 | } | 189 | } |
| 190 | |||
| 191 | transport_init_se_cmd(se_cmd, tl_tpg->tl_se_tpg.se_tpg_tfo, | ||
| 192 | tl_nexus->se_sess, | ||
| 193 | scsi_bufflen(sc), sc->sc_data_direction, | ||
| 194 | tcm_loop_sam_attr(sc), &tl_cmd->tl_sense_buf[0]); | ||
| 195 | |||
| 196 | if (scsi_bidi_cmnd(sc)) { | 190 | if (scsi_bidi_cmnd(sc)) { |
| 197 | struct scsi_data_buffer *sdb = scsi_in(sc); | 191 | struct scsi_data_buffer *sdb = scsi_in(sc); |
| 198 | 192 | ||
| @@ -201,56 +195,16 @@ static void tcm_loop_submission_work(struct work_struct *work) | |||
| 201 | se_cmd->se_cmd_flags |= SCF_BIDI; | 195 | se_cmd->se_cmd_flags |= SCF_BIDI; |
| 202 | 196 | ||
| 203 | } | 197 | } |
| 204 | 198 | rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd, | |
| 205 | if (transport_lookup_cmd_lun(se_cmd, tl_cmd->sc->device->lun) < 0) { | 199 | &tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun, |
| 206 | kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); | 200 | scsi_bufflen(sc), tcm_loop_sam_attr(sc), |
| 201 | sc->sc_data_direction, 0, | ||
| 202 | scsi_sglist(sc), scsi_sg_count(sc), | ||
| 203 | sgl_bidi, sgl_bidi_count); | ||
| 204 | if (rc < 0) { | ||
| 207 | set_host_byte(sc, DID_NO_CONNECT); | 205 | set_host_byte(sc, DID_NO_CONNECT); |
| 208 | goto out_done; | 206 | goto out_done; |
| 209 | } | 207 | } |
| 210 | |||
| 211 | /* | ||
| 212 | * Because some userspace code via scsi-generic do not memset their | ||
| 213 | * associated read buffers, go ahead and do that here for type | ||
| 214 | * non-data CDBs. Also note that this is currently guaranteed to be a | ||
| 215 | * single SGL for this case by target core in | ||
| 216 | * target_setup_cmd_from_cdb() -> transport_generic_cmd_sequencer(). | ||
| 217 | */ | ||
| 218 | if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && | ||
| 219 | se_cmd->data_direction == DMA_FROM_DEVICE) { | ||
| 220 | struct scatterlist *sg = scsi_sglist(sc); | ||
| 221 | unsigned char *buf = kmap(sg_page(sg)) + sg->offset; | ||
| 222 | |||
| 223 | if (buf != NULL) { | ||
| 224 | memset(buf, 0, sg->length); | ||
| 225 | kunmap(sg_page(sg)); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | ret = target_setup_cmd_from_cdb(se_cmd, sc->cmnd); | ||
| 230 | if (ret == -ENOMEM) { | ||
| 231 | transport_send_check_condition_and_sense(se_cmd, | ||
| 232 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); | ||
| 233 | transport_generic_free_cmd(se_cmd, 0); | ||
| 234 | return; | ||
| 235 | } else if (ret < 0) { | ||
| 236 | if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) | ||
| 237 | tcm_loop_queue_status(se_cmd); | ||
| 238 | else | ||
| 239 | transport_send_check_condition_and_sense(se_cmd, | ||
| 240 | se_cmd->scsi_sense_reason, 0); | ||
| 241 | transport_generic_free_cmd(se_cmd, 0); | ||
| 242 | return; | ||
| 243 | } | ||
| 244 | |||
| 245 | ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), | ||
| 246 | scsi_sg_count(sc), sgl_bidi, sgl_bidi_count); | ||
| 247 | if (ret) { | ||
| 248 | transport_send_check_condition_and_sense(se_cmd, | ||
| 249 | se_cmd->scsi_sense_reason, 0); | ||
| 250 | transport_generic_free_cmd(se_cmd, 0); | ||
| 251 | return; | ||
| 252 | } | ||
| 253 | transport_handle_cdb_direct(se_cmd); | ||
| 254 | return; | 208 | return; |
| 255 | 209 | ||
| 256 | out_done: | 210 | out_done: |
