aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-10-18 06:57:01 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2011-10-23 23:21:57 -0400
commitda0f7619913751d45fc3cda652789379f4f435fb (patch)
treea719ef4746505d51d13a1997de93ab5466db2687 /drivers/target
parent7c1c6af37af69a4ac4a6485c968496d257245b5d (diff)
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.c129
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,
77 struct se_device *dev); 77 struct se_device *dev);
78static void transport_direct_request_timeout(struct se_cmd *cmd); 78static void transport_direct_request_timeout(struct se_cmd *cmd);
79static void transport_free_dev_tasks(struct se_cmd *cmd); 79static void transport_free_dev_tasks(struct se_cmd *cmd);
80static u32 transport_allocate_tasks(struct se_cmd *cmd,
81 unsigned long long starting_lba,
82 enum dma_data_direction data_direction,
83 struct scatterlist *sgl, unsigned int nents);
84static int transport_generic_get_mem(struct se_cmd *cmd); 80static int transport_generic_get_mem(struct se_cmd *cmd);
85static void transport_put_cmd(struct se_cmd *cmd); 81static void transport_put_cmd(struct se_cmd *cmd);
86static void transport_remove_cmd_from_queue(struct se_cmd *cmd); 82static void transport_remove_cmd_from_queue(struct se_cmd *cmd);
@@ -3666,62 +3662,6 @@ int transport_generic_map_mem_to_cmd(
3666} 3662}
3667EXPORT_SYMBOL(transport_generic_map_mem_to_cmd); 3663EXPORT_SYMBOL(transport_generic_map_mem_to_cmd);
3668 3664
3669static int transport_new_cmd_obj(struct se_cmd *cmd)
3670{
3671 struct se_device *dev = cmd->se_dev;
3672 int set_counts = 1, rc, task_cdbs;
3673
3674 /*
3675 * Setup any BIDI READ tasks and memory from
3676 * cmd->t_mem_bidi_list so the READ struct se_tasks
3677 * are queued first for the non pSCSI passthrough case.
3678 */
3679 if (cmd->t_bidi_data_sg &&
3680 (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV)) {
3681 rc = transport_allocate_tasks(cmd,
3682 cmd->t_task_lba,
3683 DMA_FROM_DEVICE,
3684 cmd->t_bidi_data_sg,
3685 cmd->t_bidi_data_nents);
3686 if (rc <= 0) {
3687 cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
3688 cmd->scsi_sense_reason =
3689 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3690 return -EINVAL;
3691 }
3692 atomic_inc(&cmd->t_fe_count);
3693 atomic_inc(&cmd->t_se_count);
3694 set_counts = 0;
3695 }
3696 /*
3697 * Setup the tasks and memory from cmd->t_mem_list
3698 * Note for BIDI transfers this will contain the WRITE payload
3699 */
3700 task_cdbs = transport_allocate_tasks(cmd,
3701 cmd->t_task_lba,
3702 cmd->data_direction,
3703 cmd->t_data_sg,
3704 cmd->t_data_nents);
3705 if (task_cdbs <= 0) {
3706 cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
3707 cmd->scsi_sense_reason =
3708 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3709 return -EINVAL;
3710 }
3711
3712 if (set_counts) {
3713 atomic_inc(&cmd->t_fe_count);
3714 atomic_inc(&cmd->t_se_count);
3715 }
3716
3717 cmd->t_task_list_num = task_cdbs;
3718
3719 atomic_set(&cmd->t_task_cdbs_left, task_cdbs);
3720 atomic_set(&cmd->t_task_cdbs_ex_left, task_cdbs);
3721 atomic_set(&cmd->t_task_cdbs_timeout_left, task_cdbs);
3722 return 0;
3723}
3724
3725void *transport_kmap_first_data_page(struct se_cmd *cmd) 3665void *transport_kmap_first_data_page(struct se_cmd *cmd)
3726{ 3666{
3727 struct scatterlist *sg = cmd->t_data_sg; 3667 struct scatterlist *sg = cmd->t_data_sg;
@@ -4000,17 +3940,16 @@ static u32 transport_allocate_tasks(
4000} 3940}
4001 3941
4002 3942
4003/* transport_generic_new_cmd(): Called from transport_processing_thread() 3943/*
4004 * 3944 * Allocate any required ressources to execute the command, and either place
4005 * Allocate storage transport resources from a set of values predefined 3945 * it on the execution queue if possible. For writes we might not have the
4006 * by transport_generic_cmd_sequencer() from the iSCSI Target RX process. 3946 * payload yet, thus notify the fabric via a call to ->write_pending instead.
4007 * Any non zero return here is treated as an "out of resource' op here.
4008 */ 3947 */
4009 /*
4010 * Generate struct se_task(s) and/or their payloads for this CDB.
4011 */
4012int transport_generic_new_cmd(struct se_cmd *cmd) 3948int transport_generic_new_cmd(struct se_cmd *cmd)
4013{ 3949{
3950 struct se_device *dev = cmd->se_dev;
3951 int task_cdbs;
3952 int set_counts = 1;
4014 int ret = 0; 3953 int ret = 0;
4015 3954
4016 /* 3955 /*
@@ -4024,16 +3963,49 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
4024 if (ret < 0) 3963 if (ret < 0)
4025 return ret; 3964 return ret;
4026 } 3965 }
3966
4027 /* 3967 /*
4028 * Call transport_new_cmd_obj() to invoke transport_allocate_tasks() for 3968 * Setup any BIDI READ tasks and memory from
4029 * control or data CDB types, and perform the map to backend subsystem 3969 * cmd->t_mem_bidi_list so the READ struct se_tasks
4030 * code from SGL memory allocated here by transport_generic_get_mem(), or 3970 * are queued first for the non pSCSI passthrough case.
4031 * via pre-existing SGL memory setup explictly by fabric module code with
4032 * transport_generic_map_mem_to_cmd().
4033 */ 3971 */
4034 ret = transport_new_cmd_obj(cmd); 3972 if (cmd->t_bidi_data_sg &&
4035 if (ret < 0) 3973 (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV)) {
4036 return ret; 3974 ret = transport_allocate_tasks(cmd,
3975 cmd->t_task_lba,
3976 DMA_FROM_DEVICE,
3977 cmd->t_bidi_data_sg,
3978 cmd->t_bidi_data_nents);
3979 if (ret <= 0)
3980 goto out_fail;
3981
3982 atomic_inc(&cmd->t_fe_count);
3983 atomic_inc(&cmd->t_se_count);
3984 set_counts = 0;
3985 }
3986 /*
3987 * Setup the tasks and memory from cmd->t_mem_list
3988 * Note for BIDI transfers this will contain the WRITE payload
3989 */
3990 task_cdbs = transport_allocate_tasks(cmd,
3991 cmd->t_task_lba,
3992 cmd->data_direction,
3993 cmd->t_data_sg,
3994 cmd->t_data_nents);
3995 if (task_cdbs <= 0)
3996 goto out_fail;
3997
3998 if (set_counts) {
3999 atomic_inc(&cmd->t_fe_count);
4000 atomic_inc(&cmd->t_se_count);
4001 }
4002
4003 cmd->t_task_list_num = task_cdbs;
4004
4005 atomic_set(&cmd->t_task_cdbs_left, task_cdbs);
4006 atomic_set(&cmd->t_task_cdbs_ex_left, task_cdbs);
4007 atomic_set(&cmd->t_task_cdbs_timeout_left, task_cdbs);
4008
4037 /* 4009 /*
4038 * For WRITEs, let the fabric know its buffer is ready.. 4010 * For WRITEs, let the fabric know its buffer is ready..
4039 * This WRITE struct se_cmd (and all of its associated struct se_task's) 4011 * 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)
4051 */ 4023 */
4052 transport_execute_tasks(cmd); 4024 transport_execute_tasks(cmd);
4053 return 0; 4025 return 0;
4026
4027out_fail:
4028 cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
4029 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
4030 return -EINVAL;
4054} 4031}
4055EXPORT_SYMBOL(transport_generic_new_cmd); 4032EXPORT_SYMBOL(transport_generic_new_cmd);
4056 4033