diff options
| -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, | |||
| 77 | struct se_device *dev); | 77 | struct se_device *dev); |
| 78 | static void transport_direct_request_timeout(struct se_cmd *cmd); | 78 | static void transport_direct_request_timeout(struct se_cmd *cmd); |
| 79 | static void transport_free_dev_tasks(struct se_cmd *cmd); | 79 | static void transport_free_dev_tasks(struct se_cmd *cmd); |
| 80 | static 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); | ||
| 84 | static int transport_generic_get_mem(struct se_cmd *cmd); | 80 | static int transport_generic_get_mem(struct se_cmd *cmd); |
| 85 | static void transport_put_cmd(struct se_cmd *cmd); | 81 | static void transport_put_cmd(struct se_cmd *cmd); |
| 86 | static void transport_remove_cmd_from_queue(struct se_cmd *cmd); | 82 | static void transport_remove_cmd_from_queue(struct se_cmd *cmd); |
| @@ -3666,62 +3662,6 @@ int transport_generic_map_mem_to_cmd( | |||
| 3666 | } | 3662 | } |
| 3667 | EXPORT_SYMBOL(transport_generic_map_mem_to_cmd); | 3663 | EXPORT_SYMBOL(transport_generic_map_mem_to_cmd); |
| 3668 | 3664 | ||
| 3669 | static 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 | |||
| 3725 | void *transport_kmap_first_data_page(struct se_cmd *cmd) | 3665 | void *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 | */ | ||
| 4012 | int transport_generic_new_cmd(struct se_cmd *cmd) | 3948 | int 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 | |||
| 4027 | out_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 | } |
| 4055 | EXPORT_SYMBOL(transport_generic_new_cmd); | 4032 | EXPORT_SYMBOL(transport_generic_new_cmd); |
| 4056 | 4033 | ||
