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 | |
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')
-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: |