aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-10-17 13:56:41 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2011-10-23 23:21:32 -0400
commite057f53308a5f071556ee80586b99ee755bf07f5 (patch)
tree560174961d64837f53b32f56bced6f9109717b8b
parentf55918fa3202a646dad2404f7de008108edc5048 (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.c79
-rw-r--r--include/target/target_core_base.h2
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 *);
72static int transport_processing_thread(void *param); 72static int transport_processing_thread(void *param);
73static int __transport_execute_tasks(struct se_device *dev); 73static int __transport_execute_tasks(struct se_device *dev);
74static void transport_complete_task_attr(struct se_cmd *cmd); 74static void transport_complete_task_attr(struct se_cmd *cmd);
75static int transport_complete_qf(struct se_cmd *cmd);
76static void transport_handle_queue_full(struct se_cmd *cmd, 75static 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);
78static void transport_direct_request_timeout(struct se_cmd *cmd); 77static void transport_direct_request_timeout(struct se_cmd *cmd);
79static void transport_free_dev_tasks(struct se_cmd *cmd); 78static void transport_free_dev_tasks(struct se_cmd *cmd);
80static u32 transport_allocate_tasks(struct se_cmd *cmd, 79static 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
1970queue_full: 1969queue_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
1975static void transport_direct_request_timeout(struct se_cmd *cmd) 1974static 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
3434static int transport_complete_qf(struct se_cmd *cmd) 3433static 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; 3465out:
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
3462static void transport_handle_queue_full( 3474static 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
3578done:
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:
3583queue_full: 3584queue_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
3589static void transport_free_dev_tasks(struct se_cmd *cmd) 3591static void transport_free_dev_tasks(struct se_cmd *cmd)
@@ -4110,15 +4112,15 @@ void transport_generic_process_write(struct se_cmd *cmd)
4110} 4112}
4111EXPORT_SYMBOL(transport_generic_process_write); 4113EXPORT_SYMBOL(transport_generic_process_write);
4112 4114
4113static int transport_write_pending_qf(struct se_cmd *cmd) 4115static 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 */
4122static int transport_generic_write_pending(struct se_cmd *cmd) 4124static 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)
4163queue_full: 4154queue_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];