diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-10-18 06:57:01 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-10-24 03:21:57 +0000 |
commit | da0f7619913751d45fc3cda652789379f4f435fb (patch) | |
tree | a719ef4746505d51d13a1997de93ab5466db2687 /drivers/target | |
parent | 7c1c6af37af69a4ac4a6485c968496d257245b5d (diff) | |
download | linux-da0f7619913751d45fc3cda652789379f4f435fb.tar.gz |
target: merge transport_new_cmd_obj into transport_generic_new_cmd
These are two fairly small functions, and merging them gives a much
more readable control flow, and opportunities for more useful comments.
It also moves all code related to resources allocation closer together
and allows to remove a forward declaration for transport_allocate_tasks.
Signed-off-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/target_core_transport.c | 129 |
1 files changed, 53 insertions, 76 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 624d86ea083b..2fb6a2594429 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -77,10 +77,6 @@ static void transport_handle_queue_full(struct se_cmd *cmd, struct se_device *dev); static void transport_direct_request_timeout(struct se_cmd *cmd); static void transport_free_dev_tasks(struct se_cmd *cmd); -static u32 transport_allocate_tasks(struct se_cmd *cmd, - unsigned long long starting_lba, - enum dma_data_direction data_direction, - struct scatterlist *sgl, unsigned int nents); static int transport_generic_get_mem(struct se_cmd *cmd); static void transport_put_cmd(struct se_cmd *cmd); static void transport_remove_cmd_from_queue(struct se_cmd *cmd); @@ -3666,62 +3662,6 @@ int transport_generic_map_mem_to_cmd( } EXPORT_SYMBOL(transport_generic_map_mem_to_cmd); -static int transport_new_cmd_obj(struct se_cmd *cmd) -{ - struct se_device *dev = cmd->se_dev; - int set_counts = 1, rc, task_cdbs; - - /* - * Setup any BIDI READ tasks and memory from - * cmd->t_mem_bidi_list so the READ struct se_tasks - * are queued first for the non pSCSI passthrough case. - */ - if (cmd->t_bidi_data_sg && - (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV)) { - rc = transport_allocate_tasks(cmd, - cmd->t_task_lba, - DMA_FROM_DEVICE, - cmd->t_bidi_data_sg, - cmd->t_bidi_data_nents); - if (rc <= 0) { - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; - } - atomic_inc(&cmd->t_fe_count); - atomic_inc(&cmd->t_se_count); - set_counts = 0; - } - /* - * Setup the tasks and memory from cmd->t_mem_list - * Note for BIDI transfers this will contain the WRITE payload - */ - task_cdbs = transport_allocate_tasks(cmd, - cmd->t_task_lba, - cmd->data_direction, - cmd->t_data_sg, - cmd->t_data_nents); - if (task_cdbs <= 0) { - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; - } - - if (set_counts) { - atomic_inc(&cmd->t_fe_count); - atomic_inc(&cmd->t_se_count); - } - - cmd->t_task_list_num = task_cdbs; - - atomic_set(&cmd->t_task_cdbs_left, task_cdbs); - atomic_set(&cmd->t_task_cdbs_ex_left, task_cdbs); - atomic_set(&cmd->t_task_cdbs_timeout_left, task_cdbs); - return 0; -} - void *transport_kmap_first_data_page(struct se_cmd *cmd) { struct scatterlist *sg = cmd->t_data_sg; @@ -4000,17 +3940,16 @@ static u32 transport_allocate_tasks( } -/* transport_generic_new_cmd(): Called from transport_processing_thread() - * - * Allocate storage transport resources from a set of values predefined - * by transport_generic_cmd_sequencer() from the iSCSI Target RX process. - * Any non zero return here is treated as an "out of resource' op here. +/* + * Allocate any required ressources to execute the command, and either place + * it on the execution queue if possible. For writes we might not have the + * payload yet, thus notify the fabric via a call to ->write_pending instead. */ - /* - * Generate struct se_task(s) and/or their payloads for this CDB. - */ int transport_generic_new_cmd(struct se_cmd *cmd) { + struct se_device *dev = cmd->se_dev; + int task_cdbs; + int set_counts = 1; int ret = 0; /* @@ -4024,16 +3963,49 @@ int transport_generic_new_cmd(struct se_cmd *cmd) if (ret < 0) return ret; } + /* - * Call transport_new_cmd_obj() to invoke transport_allocate_tasks() for - * control or data CDB types, and perform the map to backend subsystem - * code from SGL memory allocated here by transport_generic_get_mem(), or - * via pre-existing SGL memory setup explictly by fabric module code with - * transport_generic_map_mem_to_cmd(). + * Setup any BIDI READ tasks and memory from + * cmd->t_mem_bidi_list so the READ struct se_tasks + * are queued first for the non pSCSI passthrough case. */ - ret = transport_new_cmd_obj(cmd); - if (ret < 0) - return ret; + if (cmd->t_bidi_data_sg && + (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV)) { + ret = transport_allocate_tasks(cmd, + cmd->t_task_lba, + DMA_FROM_DEVICE, + cmd->t_bidi_data_sg, + cmd->t_bidi_data_nents); + if (ret <= 0) + goto out_fail; + + atomic_inc(&cmd->t_fe_count); + atomic_inc(&cmd->t_se_count); + set_counts = 0; + } + /* + * Setup the tasks and memory from cmd->t_mem_list + * Note for BIDI transfers this will contain the WRITE payload + */ + task_cdbs = transport_allocate_tasks(cmd, + cmd->t_task_lba, + cmd->data_direction, + cmd->t_data_sg, + cmd->t_data_nents); + if (task_cdbs <= 0) + goto out_fail; + + if (set_counts) { + atomic_inc(&cmd->t_fe_count); + atomic_inc(&cmd->t_se_count); + } + + cmd->t_task_list_num = task_cdbs; + + atomic_set(&cmd->t_task_cdbs_left, task_cdbs); + atomic_set(&cmd->t_task_cdbs_ex_left, task_cdbs); + atomic_set(&cmd->t_task_cdbs_timeout_left, task_cdbs); + /* * For WRITEs, let the fabric know its buffer is ready.. * This WRITE struct se_cmd (and all of its associated struct se_task's) @@ -4051,6 +4023,11 @@ int transport_generic_new_cmd(struct se_cmd *cmd) */ transport_execute_tasks(cmd); return 0; + +out_fail: + cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; + cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + return -EINVAL; } EXPORT_SYMBOL(transport_generic_new_cmd); |