diff options
| author | Christoph Hellwig <hch@infradead.org> | 2012-02-02 17:04:40 -0500 |
|---|---|---|
| committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-02-25 17:37:48 -0500 |
| commit | f872c9f417a38a08b6ffe46e1f937d3db1d22775 (patch) | |
| tree | c475f8e56b369bd8d03343e97ab171ef6cfe0ac5 /drivers/target/loopback | |
| parent | 59dcb5ec47965d8d22428db67cbea33a9ec4f347 (diff) | |
tcm_loop: kill tcm_loop_allocate_core_cmd
This function makes little sense as a separate abstraction as it's deeply
interwinded with the control flow of its only caller. Merged it into
tcm_loop_queuecommand after factoring out a helper to convert the task
attribute representation.
Signed-off-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 | 147 |
1 files changed, 59 insertions, 88 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 7cfbcb00b3c3..b1edc517f4e3 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c | |||
| @@ -49,81 +49,6 @@ static struct kmem_cache *tcm_loop_cmd_cache; | |||
| 49 | static int tcm_loop_hba_no_cnt; | 49 | static int tcm_loop_hba_no_cnt; |
| 50 | 50 | ||
| 51 | /* | 51 | /* |
| 52 | * Allocate a tcm_loop cmd descriptor from target_core_mod code | ||
| 53 | * | ||
| 54 | * Can be called from interrupt context in tcm_loop_queuecommand() below | ||
| 55 | */ | ||
| 56 | static struct se_cmd *tcm_loop_allocate_core_cmd( | ||
| 57 | struct tcm_loop_hba *tl_hba, | ||
| 58 | struct se_portal_group *se_tpg, | ||
| 59 | struct scsi_cmnd *sc) | ||
| 60 | { | ||
| 61 | struct se_cmd *se_cmd; | ||
| 62 | struct se_session *se_sess; | ||
| 63 | struct tcm_loop_nexus *tl_nexus = tl_hba->tl_nexus; | ||
| 64 | struct tcm_loop_cmd *tl_cmd; | ||
| 65 | int sam_task_attr; | ||
| 66 | |||
| 67 | if (!tl_nexus) { | ||
| 68 | scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus" | ||
| 69 | " does not exist\n"); | ||
| 70 | set_host_byte(sc, DID_ERROR); | ||
| 71 | return NULL; | ||
| 72 | } | ||
| 73 | se_sess = tl_nexus->se_sess; | ||
| 74 | |||
| 75 | tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_ATOMIC); | ||
| 76 | if (!tl_cmd) { | ||
| 77 | pr_err("Unable to allocate struct tcm_loop_cmd\n"); | ||
| 78 | set_host_byte(sc, DID_ERROR); | ||
| 79 | return NULL; | ||
| 80 | } | ||
| 81 | se_cmd = &tl_cmd->tl_se_cmd; | ||
| 82 | /* | ||
| 83 | * Save the pointer to struct scsi_cmnd *sc | ||
| 84 | */ | ||
| 85 | tl_cmd->sc = sc; | ||
| 86 | /* | ||
| 87 | * Locate the SAM Task Attr from struct scsi_cmnd * | ||
| 88 | */ | ||
| 89 | if (sc->device->tagged_supported) { | ||
| 90 | switch (sc->tag) { | ||
| 91 | case HEAD_OF_QUEUE_TAG: | ||
| 92 | sam_task_attr = MSG_HEAD_TAG; | ||
| 93 | break; | ||
| 94 | case ORDERED_QUEUE_TAG: | ||
| 95 | sam_task_attr = MSG_ORDERED_TAG; | ||
| 96 | break; | ||
| 97 | default: | ||
| 98 | sam_task_attr = MSG_SIMPLE_TAG; | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | } else | ||
| 102 | sam_task_attr = MSG_SIMPLE_TAG; | ||
| 103 | |||
| 104 | /* | ||
| 105 | * Initialize struct se_cmd descriptor from target_core_mod infrastructure | ||
| 106 | */ | ||
| 107 | transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, | ||
| 108 | scsi_bufflen(sc), sc->sc_data_direction, sam_task_attr, | ||
| 109 | &tl_cmd->tl_sense_buf[0]); | ||
| 110 | |||
| 111 | if (scsi_bidi_cmnd(sc)) | ||
| 112 | se_cmd->se_cmd_flags |= SCF_BIDI; | ||
| 113 | |||
| 114 | /* | ||
| 115 | * Locate the struct se_lun pointer and attach it to struct se_cmd | ||
| 116 | */ | ||
| 117 | if (transport_lookup_cmd_lun(se_cmd, tl_cmd->sc->device->lun) < 0) { | ||
| 118 | kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); | ||
| 119 | set_host_byte(sc, DID_NO_CONNECT); | ||
| 120 | return NULL; | ||
| 121 | } | ||
| 122 | |||
| 123 | return se_cmd; | ||
| 124 | } | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Called by struct target_core_fabric_ops->new_cmd_map() | 52 | * Called by struct target_core_fabric_ops->new_cmd_map() |
| 128 | * | 53 | * |
| 129 | * Always called in process context. A non zero return value | 54 | * Always called in process context. A non zero return value |
| @@ -263,6 +188,25 @@ static int tcm_loop_change_queue_depth( | |||
| 263 | } | 188 | } |
| 264 | 189 | ||
| 265 | /* | 190 | /* |
| 191 | * Locate the SAM Task Attr from struct scsi_cmnd * | ||
| 192 | */ | ||
| 193 | static int tcm_loop_sam_attr(struct scsi_cmnd *sc) | ||
| 194 | { | ||
| 195 | if (sc->device->tagged_supported) { | ||
| 196 | switch (sc->tag) { | ||
| 197 | case HEAD_OF_QUEUE_TAG: | ||
| 198 | return MSG_HEAD_TAG; | ||
| 199 | case ORDERED_QUEUE_TAG: | ||
| 200 | return MSG_ORDERED_TAG; | ||
| 201 | default: | ||
| 202 | break; | ||
| 203 | } | ||
| 204 | } | ||
| 205 | |||
| 206 | return MSG_SIMPLE_TAG; | ||
| 207 | } | ||
| 208 | |||
| 209 | /* | ||
| 266 | * Main entry point from struct scsi_host_template for incoming SCSI CDB+Data | 210 | * Main entry point from struct scsi_host_template for incoming SCSI CDB+Data |
| 267 | * from Linux/SCSI subsystem for SCSI low level device drivers (LLDs) | 211 | * from Linux/SCSI subsystem for SCSI low level device drivers (LLDs) |
| 268 | */ | 212 | */ |
| @@ -274,6 +218,10 @@ static int tcm_loop_queuecommand( | |||
| 274 | struct se_portal_group *se_tpg; | 218 | struct se_portal_group *se_tpg; |
| 275 | struct tcm_loop_hba *tl_hba; | 219 | struct tcm_loop_hba *tl_hba; |
| 276 | struct tcm_loop_tpg *tl_tpg; | 220 | struct tcm_loop_tpg *tl_tpg; |
| 221 | struct se_session *se_sess; | ||
| 222 | struct tcm_loop_nexus *tl_nexus; | ||
| 223 | struct tcm_loop_cmd *tl_cmd; | ||
| 224 | |||
| 277 | 225 | ||
| 278 | pr_debug("tcm_loop_queuecommand() %d:%d:%d:%d got CDB: 0x%02x" | 226 | pr_debug("tcm_loop_queuecommand() %d:%d:%d:%d got CDB: 0x%02x" |
| 279 | " scsi_buf_len: %u\n", sc->device->host->host_no, | 227 | " scsi_buf_len: %u\n", sc->device->host->host_no, |
| @@ -290,24 +238,47 @@ static int tcm_loop_queuecommand( | |||
| 290 | */ | 238 | */ |
| 291 | if (!tl_tpg->tl_hba) { | 239 | if (!tl_tpg->tl_hba) { |
| 292 | set_host_byte(sc, DID_NO_CONNECT); | 240 | set_host_byte(sc, DID_NO_CONNECT); |
| 293 | sc->scsi_done(sc); | 241 | goto out_done; |
| 294 | return 0; | ||
| 295 | } | 242 | } |
| 296 | se_tpg = &tl_tpg->tl_se_tpg; | 243 | se_tpg = &tl_tpg->tl_se_tpg; |
| 297 | /* | 244 | |
| 298 | * Determine the SAM Task Attribute and allocate tl_cmd and | 245 | tl_nexus = tl_hba->tl_nexus; |
| 299 | * tl_cmd->tl_se_cmd from TCM infrastructure | 246 | if (!tl_nexus) { |
| 300 | */ | 247 | scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus" |
| 301 | se_cmd = tcm_loop_allocate_core_cmd(tl_hba, se_tpg, sc); | 248 | " does not exist\n"); |
| 302 | if (!se_cmd) { | 249 | set_host_byte(sc, DID_ERROR); |
| 303 | sc->scsi_done(sc); | 250 | goto out_done; |
| 304 | return 0; | ||
| 305 | } | 251 | } |
| 306 | /* | 252 | se_sess = tl_nexus->se_sess; |
| 307 | * Queue up the newly allocated to be processed in TCM thread context. | 253 | |
| 308 | */ | 254 | tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_ATOMIC); |
| 255 | if (!tl_cmd) { | ||
| 256 | pr_err("Unable to allocate struct tcm_loop_cmd\n"); | ||
| 257 | set_host_byte(sc, DID_ERROR); | ||
| 258 | goto out_done; | ||
| 259 | } | ||
| 260 | se_cmd = &tl_cmd->tl_se_cmd; | ||
| 261 | tl_cmd->sc = sc; | ||
| 262 | |||
| 263 | transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, | ||
| 264 | scsi_bufflen(sc), sc->sc_data_direction, | ||
| 265 | tcm_loop_sam_attr(sc), &tl_cmd->tl_sense_buf[0]); | ||
| 266 | |||
| 267 | if (scsi_bidi_cmnd(sc)) | ||
| 268 | se_cmd->se_cmd_flags |= SCF_BIDI; | ||
| 269 | |||
| 270 | if (transport_lookup_cmd_lun(se_cmd, tl_cmd->sc->device->lun) < 0) { | ||
| 271 | kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); | ||
| 272 | set_host_byte(sc, DID_NO_CONNECT); | ||
| 273 | goto out_done; | ||
| 274 | } | ||
| 275 | |||
| 309 | transport_generic_handle_cdb_map(se_cmd); | 276 | transport_generic_handle_cdb_map(se_cmd); |
| 310 | return 0; | 277 | return 0; |
| 278 | |||
| 279 | out_done: | ||
| 280 | sc->scsi_done(sc); | ||
| 281 | return 0; | ||
| 311 | } | 282 | } |
| 312 | 283 | ||
| 313 | /* | 284 | /* |
