aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2008-10-29 09:46:45 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-12-29 12:24:13 -0500
commit10e794996ed00a0f09ff0745f87e3a3dd5de4606 (patch)
treec5bb008170708e1d63e09e813e30257c5fcac7ce
parentad8dcffaf9bc1d7eb86dabf591e95f4ffb86cf1b (diff)
[SCSI] ibmvfc: Fix target initialization failure retry handling
If the ibmvfc driver is in discovery attempting to log into a target and it encounters an error, the command may get retried one or more times, depending on the error received. If the retries are unsuccessful such that the discovery thread gives up on discovery to that target, the target ends up in a state where, if SCSI core had previously known about the device, the host will get unblocked but the host will not be logged into the target, causing any commands sent to the target to fail. This patch fixes this so that if this occurs, the target is deleted such that the normal dev_loss processing can occur instead. Signed-off-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c42
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h1
2 files changed, 23 insertions, 20 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index af69c0738edb..844684581e45 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -496,6 +496,7 @@ static void ibmvfc_set_host_action(struct ibmvfc_host *vhost,
496 case IBMVFC_HOST_ACTION_INIT: 496 case IBMVFC_HOST_ACTION_INIT:
497 case IBMVFC_HOST_ACTION_TGT_DEL: 497 case IBMVFC_HOST_ACTION_TGT_DEL:
498 case IBMVFC_HOST_ACTION_QUERY_TGTS: 498 case IBMVFC_HOST_ACTION_QUERY_TGTS:
499 case IBMVFC_HOST_ACTION_TGT_DEL_FAILED:
499 case IBMVFC_HOST_ACTION_TGT_ADD: 500 case IBMVFC_HOST_ACTION_TGT_ADD:
500 case IBMVFC_HOST_ACTION_NONE: 501 case IBMVFC_HOST_ACTION_NONE:
501 default: 502 default:
@@ -2791,6 +2792,8 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
2791 rsp->status, rsp->error, status); 2792 rsp->status, rsp->error, status);
2792 if (ibmvfc_retry_cmd(rsp->status, rsp->error)) 2793 if (ibmvfc_retry_cmd(rsp->status, rsp->error))
2793 ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli); 2794 ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
2795 else
2796 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
2794 break; 2797 break;
2795 }; 2798 };
2796 2799
@@ -2885,6 +2888,8 @@ static void ibmvfc_tgt_plogi_done(struct ibmvfc_event *evt)
2885 2888
2886 if (ibmvfc_retry_cmd(rsp->status, rsp->error)) 2889 if (ibmvfc_retry_cmd(rsp->status, rsp->error))
2887 ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi); 2890 ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi);
2891 else
2892 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
2888 break; 2893 break;
2889 }; 2894 };
2890 2895
@@ -3176,6 +3181,8 @@ static void ibmvfc_tgt_query_target_done(struct ibmvfc_event *evt)
3176 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); 3181 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3177 else if (ibmvfc_retry_cmd(rsp->status, rsp->error)) 3182 else if (ibmvfc_retry_cmd(rsp->status, rsp->error))
3178 ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_query_target); 3183 ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_query_target);
3184 else
3185 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3179 break; 3186 break;
3180 }; 3187 };
3181 3188
@@ -3506,6 +3513,7 @@ static int __ibmvfc_work_to_do(struct ibmvfc_host *vhost)
3506 case IBMVFC_HOST_ACTION_ALLOC_TGTS: 3513 case IBMVFC_HOST_ACTION_ALLOC_TGTS:
3507 case IBMVFC_HOST_ACTION_TGT_ADD: 3514 case IBMVFC_HOST_ACTION_TGT_ADD:
3508 case IBMVFC_HOST_ACTION_TGT_DEL: 3515 case IBMVFC_HOST_ACTION_TGT_DEL:
3516 case IBMVFC_HOST_ACTION_TGT_DEL_FAILED:
3509 case IBMVFC_HOST_ACTION_QUERY: 3517 case IBMVFC_HOST_ACTION_QUERY:
3510 default: 3518 default:
3511 break; 3519 break;
@@ -3621,6 +3629,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
3621 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_DEL); 3629 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_DEL);
3622 break; 3630 break;
3623 case IBMVFC_HOST_ACTION_TGT_DEL: 3631 case IBMVFC_HOST_ACTION_TGT_DEL:
3632 case IBMVFC_HOST_ACTION_TGT_DEL_FAILED:
3624 list_for_each_entry(tgt, &vhost->targets, queue) { 3633 list_for_each_entry(tgt, &vhost->targets, queue) {
3625 if (tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) { 3634 if (tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) {
3626 tgt_dbg(tgt, "Deleting rport\n"); 3635 tgt_dbg(tgt, "Deleting rport\n");
@@ -3636,8 +3645,17 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
3636 } 3645 }
3637 3646
3638 if (vhost->state == IBMVFC_INITIALIZING) { 3647 if (vhost->state == IBMVFC_INITIALIZING) {
3639 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT); 3648 if (vhost->action == IBMVFC_HOST_ACTION_TGT_DEL_FAILED) {
3640 vhost->job_step = ibmvfc_discover_targets; 3649 ibmvfc_set_host_state(vhost, IBMVFC_ACTIVE);
3650 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_ADD);
3651 vhost->init_retries = 0;
3652 spin_unlock_irqrestore(vhost->host->host_lock, flags);
3653 scsi_unblock_requests(vhost->host);
3654 return;
3655 } else {
3656 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT);
3657 vhost->job_step = ibmvfc_discover_targets;
3658 }
3641 } else { 3659 } else {
3642 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE); 3660 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE);
3643 spin_unlock_irqrestore(vhost->host->host_lock, flags); 3661 spin_unlock_irqrestore(vhost->host->host_lock, flags);
@@ -3660,14 +3678,8 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
3660 } 3678 }
3661 } 3679 }
3662 3680
3663 if (!ibmvfc_dev_init_to_do(vhost)) { 3681 if (!ibmvfc_dev_init_to_do(vhost))
3664 ibmvfc_set_host_state(vhost, IBMVFC_ACTIVE); 3682 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_DEL_FAILED);
3665 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_ADD);
3666 vhost->init_retries = 0;
3667 spin_unlock_irqrestore(vhost->host->host_lock, flags);
3668 scsi_unblock_requests(vhost->host);
3669 return;
3670 }
3671 break; 3683 break;
3672 case IBMVFC_HOST_ACTION_TGT_ADD: 3684 case IBMVFC_HOST_ACTION_TGT_ADD:
3673 list_for_each_entry(tgt, &vhost->targets, queue) { 3685 list_for_each_entry(tgt, &vhost->targets, queue) {
@@ -3675,16 +3687,6 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
3675 spin_unlock_irqrestore(vhost->host->host_lock, flags); 3687 spin_unlock_irqrestore(vhost->host->host_lock, flags);
3676 ibmvfc_tgt_add_rport(tgt); 3688 ibmvfc_tgt_add_rport(tgt);
3677 return; 3689 return;
3678 } else if (tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) {
3679 tgt_dbg(tgt, "Deleting rport\n");
3680 rport = tgt->rport;
3681 tgt->rport = NULL;
3682 list_del(&tgt->queue);
3683 spin_unlock_irqrestore(vhost->host->host_lock, flags);
3684 if (rport)
3685 fc_remote_port_delete(rport);
3686 kref_put(&tgt->kref, ibmvfc_release_tgt);
3687 return;
3688 } 3690 }
3689 } 3691 }
3690 3692
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index c3696ce470bd..2d723df5b18c 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -626,6 +626,7 @@ enum ibmvfc_host_action {
626 IBMVFC_HOST_ACTION_TGT_DEL, 626 IBMVFC_HOST_ACTION_TGT_DEL,
627 IBMVFC_HOST_ACTION_ALLOC_TGTS, 627 IBMVFC_HOST_ACTION_ALLOC_TGTS,
628 IBMVFC_HOST_ACTION_TGT_INIT, 628 IBMVFC_HOST_ACTION_TGT_INIT,
629 IBMVFC_HOST_ACTION_TGT_DEL_FAILED,
629 IBMVFC_HOST_ACTION_TGT_ADD, 630 IBMVFC_HOST_ACTION_TGT_ADD,
630}; 631};
631 632