diff options
author | Christoph Hellwig <hch@infradead.org> | 2012-07-08 15:58:41 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-07-16 20:35:17 -0400 |
commit | c3196f0cf0061ae62660b3d9a6ce736bef817aba (patch) | |
tree | ab524c83c5f0bb89981a344080d2cebd75581aef /drivers/target | |
parent | d59a02b4ebe6fe5ac42b702f1ced6368ced78d76 (diff) |
target: merge transport_generic_write_pending into transport_generic_new_cmd
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 | 74 |
1 files changed, 26 insertions, 48 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index dd9c87f62d76..db139133f708 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -66,7 +66,6 @@ struct kmem_cache *t10_alua_lu_gp_mem_cache; | |||
66 | struct kmem_cache *t10_alua_tg_pt_gp_cache; | 66 | struct kmem_cache *t10_alua_tg_pt_gp_cache; |
67 | struct kmem_cache *t10_alua_tg_pt_gp_mem_cache; | 67 | struct kmem_cache *t10_alua_tg_pt_gp_mem_cache; |
68 | 68 | ||
69 | static int transport_generic_write_pending(struct se_cmd *); | ||
70 | static int transport_processing_thread(void *param); | 69 | static int transport_processing_thread(void *param); |
71 | static void transport_complete_task_attr(struct se_cmd *cmd); | 70 | static void transport_complete_task_attr(struct se_cmd *cmd); |
72 | static void transport_handle_queue_full(struct se_cmd *cmd, | 71 | static void transport_handle_queue_full(struct se_cmd *cmd, |
@@ -2487,23 +2486,39 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
2487 | atomic_inc(&cmd->t_fe_count); | 2486 | atomic_inc(&cmd->t_fe_count); |
2488 | 2487 | ||
2489 | /* | 2488 | /* |
2490 | * For WRITEs, let the fabric know its buffer is ready. | 2489 | * If this command is not a write we can execute it right here, |
2491 | * | 2490 | * for write buffers we need to notify the fabric driver first |
2492 | * The command will be added to the execution queue after its write | 2491 | * and let it call back once the write buffers are ready. |
2493 | * data has arrived. | ||
2494 | * | ||
2495 | * Everything else but a WRITE, add the command to the execution queue. | ||
2496 | */ | 2492 | */ |
2497 | target_add_to_state_list(cmd); | 2493 | target_add_to_state_list(cmd); |
2498 | if (cmd->data_direction == DMA_TO_DEVICE) | 2494 | if (cmd->data_direction != DMA_TO_DEVICE) { |
2499 | return transport_generic_write_pending(cmd); | 2495 | target_execute_cmd(cmd); |
2500 | target_execute_cmd(cmd); | 2496 | return 0; |
2501 | return 0; | 2497 | } |
2498 | |||
2499 | spin_lock_irq(&cmd->t_state_lock); | ||
2500 | cmd->t_state = TRANSPORT_WRITE_PENDING; | ||
2501 | spin_unlock_irq(&cmd->t_state_lock); | ||
2502 | |||
2503 | transport_cmd_check_stop(cmd, false); | ||
2504 | |||
2505 | ret = cmd->se_tfo->write_pending(cmd); | ||
2506 | if (ret == -EAGAIN || ret == -ENOMEM) | ||
2507 | goto queue_full; | ||
2508 | |||
2509 | if (ret < 0) | ||
2510 | return ret; | ||
2511 | return 1; | ||
2502 | 2512 | ||
2503 | out_fail: | 2513 | out_fail: |
2504 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 2514 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; |
2505 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2515 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2506 | return -EINVAL; | 2516 | return -EINVAL; |
2517 | queue_full: | ||
2518 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); | ||
2519 | cmd->t_state = TRANSPORT_COMPLETE_QF_WP; | ||
2520 | transport_handle_queue_full(cmd, cmd->se_dev); | ||
2521 | return 0; | ||
2507 | } | 2522 | } |
2508 | EXPORT_SYMBOL(transport_generic_new_cmd); | 2523 | EXPORT_SYMBOL(transport_generic_new_cmd); |
2509 | 2524 | ||
@@ -2519,43 +2534,6 @@ static void transport_write_pending_qf(struct se_cmd *cmd) | |||
2519 | } | 2534 | } |
2520 | } | 2535 | } |
2521 | 2536 | ||
2522 | static int transport_generic_write_pending(struct se_cmd *cmd) | ||
2523 | { | ||
2524 | unsigned long flags; | ||
2525 | int ret; | ||
2526 | |||
2527 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
2528 | cmd->t_state = TRANSPORT_WRITE_PENDING; | ||
2529 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
2530 | |||
2531 | /* | ||
2532 | * Clear the se_cmd for WRITE_PENDING status in order to set | ||
2533 | * CMD_T_ACTIVE so that transport_generic_handle_data can be called | ||
2534 | * from HW target mode interrupt code. This is safe to be called | ||
2535 | * with remove_from_lists false before the cmd->se_tfo->write_pending | ||
2536 | * because the se_cmd->se_lun pointer is not being cleared. | ||
2537 | */ | ||
2538 | transport_cmd_check_stop(cmd, false); | ||
2539 | |||
2540 | /* | ||
2541 | * Call the fabric write_pending function here to let the | ||
2542 | * frontend know that WRITE buffers are ready. | ||
2543 | */ | ||
2544 | ret = cmd->se_tfo->write_pending(cmd); | ||
2545 | if (ret == -EAGAIN || ret == -ENOMEM) | ||
2546 | goto queue_full; | ||
2547 | else if (ret < 0) | ||
2548 | return ret; | ||
2549 | |||
2550 | return 1; | ||
2551 | |||
2552 | queue_full: | ||
2553 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); | ||
2554 | cmd->t_state = TRANSPORT_COMPLETE_QF_WP; | ||
2555 | transport_handle_queue_full(cmd, cmd->se_dev); | ||
2556 | return 0; | ||
2557 | } | ||
2558 | |||
2559 | void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) | 2537 | void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) |
2560 | { | 2538 | { |
2561 | if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) { | 2539 | if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) { |