diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-10-17 13:56:41 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-10-23 23:21:32 -0400 |
commit | e057f53308a5f071556ee80586b99ee755bf07f5 (patch) | |
tree | 560174961d64837f53b32f56bced6f9109717b8b | |
parent | f55918fa3202a646dad2404f7de008108edc5048 (diff) |
target: remove the transport_qf_callback se_cmd callback
Remove the need for the transport_qf_callback callback by making
sure we have specific states with specific handlers for the two
queue full cases.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/target_core_transport.c | 79 | ||||
-rw-r--r-- | include/target/target_core_base.h | 2 |
2 files changed, 37 insertions, 44 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index cb022a1b22b3..4ce205040b15 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -72,9 +72,8 @@ static int transport_generic_write_pending(struct se_cmd *); | |||
72 | static int transport_processing_thread(void *param); | 72 | static int transport_processing_thread(void *param); |
73 | static int __transport_execute_tasks(struct se_device *dev); | 73 | static int __transport_execute_tasks(struct se_device *dev); |
74 | static void transport_complete_task_attr(struct se_cmd *cmd); | 74 | static void transport_complete_task_attr(struct se_cmd *cmd); |
75 | static int transport_complete_qf(struct se_cmd *cmd); | ||
76 | static void transport_handle_queue_full(struct se_cmd *cmd, | 75 | static void transport_handle_queue_full(struct se_cmd *cmd, |
77 | struct se_device *dev, int (*qf_callback)(struct se_cmd *)); | 76 | struct se_device *dev); |
78 | static void transport_direct_request_timeout(struct se_cmd *cmd); | 77 | static void transport_direct_request_timeout(struct se_cmd *cmd); |
79 | static void transport_free_dev_tasks(struct se_cmd *cmd); | 78 | static void transport_free_dev_tasks(struct se_cmd *cmd); |
80 | static u32 transport_allocate_tasks(struct se_cmd *cmd, | 79 | static u32 transport_allocate_tasks(struct se_cmd *cmd, |
@@ -969,7 +968,7 @@ static void target_qf_do_work(struct work_struct *work) | |||
969 | 968 | ||
970 | pr_debug("Processing %s cmd: %p QUEUE_FULL in work queue" | 969 | pr_debug("Processing %s cmd: %p QUEUE_FULL in work queue" |
971 | " context: %s\n", cmd->se_tfo->get_fabric_name(), cmd, | 970 | " context: %s\n", cmd->se_tfo->get_fabric_name(), cmd, |
972 | (cmd->t_state == TRANSPORT_COMPLETE_OK) ? "COMPLETE_OK" : | 971 | (cmd->t_state == TRANSPORT_COMPLETE_QF_OK) ? "COMPLETE_OK" : |
973 | (cmd->t_state == TRANSPORT_COMPLETE_QF_WP) ? "WRITE_PENDING" | 972 | (cmd->t_state == TRANSPORT_COMPLETE_QF_WP) ? "WRITE_PENDING" |
974 | : "UNKNOWN"); | 973 | : "UNKNOWN"); |
975 | /* | 974 | /* |
@@ -1968,8 +1967,8 @@ check_stop: | |||
1968 | return; | 1967 | return; |
1969 | 1968 | ||
1970 | queue_full: | 1969 | queue_full: |
1971 | cmd->t_state = TRANSPORT_COMPLETE_OK; | 1970 | cmd->t_state = TRANSPORT_COMPLETE_QF_OK; |
1972 | transport_handle_queue_full(cmd, cmd->se_dev, transport_complete_qf); | 1971 | transport_handle_queue_full(cmd, cmd->se_dev); |
1973 | } | 1972 | } |
1974 | 1973 | ||
1975 | static void transport_direct_request_timeout(struct se_cmd *cmd) | 1974 | static void transport_direct_request_timeout(struct se_cmd *cmd) |
@@ -3431,12 +3430,19 @@ static void transport_complete_task_attr(struct se_cmd *cmd) | |||
3431 | wake_up_interruptible(&dev->dev_queue_obj.thread_wq); | 3430 | wake_up_interruptible(&dev->dev_queue_obj.thread_wq); |
3432 | } | 3431 | } |
3433 | 3432 | ||
3434 | static int transport_complete_qf(struct se_cmd *cmd) | 3433 | static void transport_complete_qf(struct se_cmd *cmd) |
3435 | { | 3434 | { |
3436 | int ret = 0; | 3435 | int ret = 0; |
3437 | 3436 | ||
3438 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) | 3437 | transport_stop_all_task_timers(cmd); |
3439 | return cmd->se_tfo->queue_status(cmd); | 3438 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) |
3439 | transport_complete_task_attr(cmd); | ||
3440 | |||
3441 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { | ||
3442 | ret = cmd->se_tfo->queue_status(cmd); | ||
3443 | if (ret) | ||
3444 | goto out; | ||
3445 | } | ||
3440 | 3446 | ||
3441 | switch (cmd->data_direction) { | 3447 | switch (cmd->data_direction) { |
3442 | case DMA_FROM_DEVICE: | 3448 | case DMA_FROM_DEVICE: |
@@ -3446,7 +3452,7 @@ static int transport_complete_qf(struct se_cmd *cmd) | |||
3446 | if (cmd->t_bidi_data_sg) { | 3452 | if (cmd->t_bidi_data_sg) { |
3447 | ret = cmd->se_tfo->queue_data_in(cmd); | 3453 | ret = cmd->se_tfo->queue_data_in(cmd); |
3448 | if (ret < 0) | 3454 | if (ret < 0) |
3449 | return ret; | 3455 | break; |
3450 | } | 3456 | } |
3451 | /* Fall through for DMA_TO_DEVICE */ | 3457 | /* Fall through for DMA_TO_DEVICE */ |
3452 | case DMA_NONE: | 3458 | case DMA_NONE: |
@@ -3456,17 +3462,21 @@ static int transport_complete_qf(struct se_cmd *cmd) | |||
3456 | break; | 3462 | break; |
3457 | } | 3463 | } |
3458 | 3464 | ||
3459 | return ret; | 3465 | out: |
3466 | if (ret < 0) { | ||
3467 | transport_handle_queue_full(cmd, cmd->se_dev); | ||
3468 | return; | ||
3469 | } | ||
3470 | transport_lun_remove_cmd(cmd); | ||
3471 | transport_cmd_check_stop_to_fabric(cmd); | ||
3460 | } | 3472 | } |
3461 | 3473 | ||
3462 | static void transport_handle_queue_full( | 3474 | static void transport_handle_queue_full( |
3463 | struct se_cmd *cmd, | 3475 | struct se_cmd *cmd, |
3464 | struct se_device *dev, | 3476 | struct se_device *dev) |
3465 | int (*qf_callback)(struct se_cmd *)) | ||
3466 | { | 3477 | { |
3467 | spin_lock_irq(&dev->qf_cmd_lock); | 3478 | spin_lock_irq(&dev->qf_cmd_lock); |
3468 | cmd->se_cmd_flags |= SCF_EMULATE_QUEUE_FULL; | 3479 | cmd->se_cmd_flags |= SCF_EMULATE_QUEUE_FULL; |
3469 | cmd->transport_qf_callback = qf_callback; | ||
3470 | list_add_tail(&cmd->se_qf_node, &cmd->se_dev->qf_cmd_list); | 3480 | list_add_tail(&cmd->se_qf_node, &cmd->se_dev->qf_cmd_list); |
3471 | atomic_inc(&dev->dev_qf_count); | 3481 | atomic_inc(&dev->dev_qf_count); |
3472 | smp_mb__after_atomic_inc(); | 3482 | smp_mb__after_atomic_inc(); |
@@ -3492,14 +3502,6 @@ static void transport_generic_complete_ok(struct se_cmd *cmd) | |||
3492 | if (atomic_read(&cmd->se_dev->dev_qf_count) != 0) | 3502 | if (atomic_read(&cmd->se_dev->dev_qf_count) != 0) |
3493 | schedule_work(&cmd->se_dev->qf_work_queue); | 3503 | schedule_work(&cmd->se_dev->qf_work_queue); |
3494 | 3504 | ||
3495 | if (cmd->transport_qf_callback) { | ||
3496 | ret = cmd->transport_qf_callback(cmd); | ||
3497 | if (ret < 0) | ||
3498 | goto queue_full; | ||
3499 | |||
3500 | cmd->transport_qf_callback = NULL; | ||
3501 | goto done; | ||
3502 | } | ||
3503 | /* | 3505 | /* |
3504 | * Check if we need to retrieve a sense buffer from | 3506 | * Check if we need to retrieve a sense buffer from |
3505 | * the struct se_cmd in question. | 3507 | * the struct se_cmd in question. |
@@ -3575,7 +3577,6 @@ static void transport_generic_complete_ok(struct se_cmd *cmd) | |||
3575 | break; | 3577 | break; |
3576 | } | 3578 | } |
3577 | 3579 | ||
3578 | done: | ||
3579 | transport_lun_remove_cmd(cmd); | 3580 | transport_lun_remove_cmd(cmd); |
3580 | transport_cmd_check_stop_to_fabric(cmd); | 3581 | transport_cmd_check_stop_to_fabric(cmd); |
3581 | return; | 3582 | return; |
@@ -3583,7 +3584,8 @@ done: | |||
3583 | queue_full: | 3584 | queue_full: |
3584 | pr_debug("Handling complete_ok QUEUE_FULL: se_cmd: %p," | 3585 | pr_debug("Handling complete_ok QUEUE_FULL: se_cmd: %p," |
3585 | " data_direction: %d\n", cmd, cmd->data_direction); | 3586 | " data_direction: %d\n", cmd, cmd->data_direction); |
3586 | transport_handle_queue_full(cmd, cmd->se_dev, transport_complete_qf); | 3587 | cmd->t_state = TRANSPORT_COMPLETE_QF_OK; |
3588 | transport_handle_queue_full(cmd, cmd->se_dev); | ||
3587 | } | 3589 | } |
3588 | 3590 | ||
3589 | static void transport_free_dev_tasks(struct se_cmd *cmd) | 3591 | static void transport_free_dev_tasks(struct se_cmd *cmd) |
@@ -4110,15 +4112,15 @@ void transport_generic_process_write(struct se_cmd *cmd) | |||
4110 | } | 4112 | } |
4111 | EXPORT_SYMBOL(transport_generic_process_write); | 4113 | EXPORT_SYMBOL(transport_generic_process_write); |
4112 | 4114 | ||
4113 | static int transport_write_pending_qf(struct se_cmd *cmd) | 4115 | static void transport_write_pending_qf(struct se_cmd *cmd) |
4114 | { | 4116 | { |
4115 | return cmd->se_tfo->write_pending(cmd); | 4117 | if (cmd->se_tfo->write_pending(cmd) == -EAGAIN) { |
4118 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", | ||
4119 | cmd); | ||
4120 | transport_handle_queue_full(cmd, cmd->se_dev); | ||
4121 | } | ||
4116 | } | 4122 | } |
4117 | 4123 | ||
4118 | /* transport_generic_write_pending(): | ||
4119 | * | ||
4120 | * | ||
4121 | */ | ||
4122 | static int transport_generic_write_pending(struct se_cmd *cmd) | 4124 | static int transport_generic_write_pending(struct se_cmd *cmd) |
4123 | { | 4125 | { |
4124 | unsigned long flags; | 4126 | unsigned long flags; |
@@ -4128,17 +4130,6 @@ static int transport_generic_write_pending(struct se_cmd *cmd) | |||
4128 | cmd->t_state = TRANSPORT_WRITE_PENDING; | 4130 | cmd->t_state = TRANSPORT_WRITE_PENDING; |
4129 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 4131 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
4130 | 4132 | ||
4131 | if (cmd->transport_qf_callback) { | ||
4132 | ret = cmd->transport_qf_callback(cmd); | ||
4133 | if (ret == -EAGAIN) | ||
4134 | goto queue_full; | ||
4135 | else if (ret < 0) | ||
4136 | return ret; | ||
4137 | |||
4138 | cmd->transport_qf_callback = NULL; | ||
4139 | return 0; | ||
4140 | } | ||
4141 | |||
4142 | /* | 4133 | /* |
4143 | * Clear the se_cmd for WRITE_PENDING status in order to set | 4134 | * Clear the se_cmd for WRITE_PENDING status in order to set |
4144 | * cmd->t_transport_active=0 so that transport_generic_handle_data | 4135 | * cmd->t_transport_active=0 so that transport_generic_handle_data |
@@ -4163,8 +4154,7 @@ static int transport_generic_write_pending(struct se_cmd *cmd) | |||
4163 | queue_full: | 4154 | queue_full: |
4164 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); | 4155 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); |
4165 | cmd->t_state = TRANSPORT_COMPLETE_QF_WP; | 4156 | cmd->t_state = TRANSPORT_COMPLETE_QF_WP; |
4166 | transport_handle_queue_full(cmd, cmd->se_dev, | 4157 | transport_handle_queue_full(cmd, cmd->se_dev); |
4167 | transport_write_pending_qf); | ||
4168 | return ret; | 4158 | return ret; |
4169 | } | 4159 | } |
4170 | 4160 | ||
@@ -4851,7 +4841,10 @@ get_cmd: | |||
4851 | transport_generic_request_timeout(cmd); | 4841 | transport_generic_request_timeout(cmd); |
4852 | break; | 4842 | break; |
4853 | case TRANSPORT_COMPLETE_QF_WP: | 4843 | case TRANSPORT_COMPLETE_QF_WP: |
4854 | transport_generic_write_pending(cmd); | 4844 | transport_write_pending_qf(cmd); |
4845 | break; | ||
4846 | case TRANSPORT_COMPLETE_QF_OK: | ||
4847 | transport_complete_qf(cmd); | ||
4855 | break; | 4848 | break; |
4856 | default: | 4849 | default: |
4857 | pr_err("Unknown t_state: %d deferred_t_state:" | 4850 | pr_err("Unknown t_state: %d deferred_t_state:" |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 16d7a4985639..2d47aa9f762a 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -102,6 +102,7 @@ enum transport_state_table { | |||
102 | TRANSPORT_NEW_CMD_MAP = 16, | 102 | TRANSPORT_NEW_CMD_MAP = 16, |
103 | TRANSPORT_FREE_CMD_INTR = 17, | 103 | TRANSPORT_FREE_CMD_INTR = 17, |
104 | TRANSPORT_COMPLETE_QF_WP = 18, | 104 | TRANSPORT_COMPLETE_QF_WP = 18, |
105 | TRANSPORT_COMPLETE_QF_OK = 19, | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | /* Used for struct se_cmd->se_cmd_flags */ | 108 | /* Used for struct se_cmd->se_cmd_flags */ |
@@ -471,7 +472,6 @@ struct se_cmd { | |||
471 | struct target_core_fabric_ops *se_tfo; | 472 | struct target_core_fabric_ops *se_tfo; |
472 | int (*transport_emulate_cdb)(struct se_cmd *); | 473 | int (*transport_emulate_cdb)(struct se_cmd *); |
473 | void (*transport_complete_callback)(struct se_cmd *); | 474 | void (*transport_complete_callback)(struct se_cmd *); |
474 | int (*transport_qf_callback)(struct se_cmd *); | ||
475 | 475 | ||
476 | unsigned char *t_task_cdb; | 476 | unsigned char *t_task_cdb; |
477 | unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE]; | 477 | unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE]; |