ibmvfc: Fix endless PRLI loop in discovery
authorBrian King <brking@linux.vnet.ibm.com>
Thu, 18 Jun 2009 14:06:55 +0000 (09:06 -0500)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Sun, 21 Jun 2009 16:09:57 +0000 (11:09 -0500)
Fixes a problem seen where sending a PRLI to a target
resulted in it sending a LOGO. This caused the ibmvfc
driver to go back through discovery again, which caused
another PRLI attempt, which caused another LOGO. Fix this
behavior by ignoring LOGO if we haven't even logged into
the target yet.

Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/ibmvscsi/ibmvfc.h

index 497a4cc4d9ef511fe38f45da92cc716988511861..166d96450a0eea134dd5b88ecfbfd48fd906a2de 100644 (file)
@@ -2254,10 +2254,13 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
                                continue;
                        if (crq->node_name && tgt->ids.node_name != crq->node_name)
                                continue;
-                       ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
+                       if (tgt->need_login && crq->event == IBMVFC_AE_ELS_LOGO)
+                               tgt->logo_rcvd = 1;
+                       if (!tgt->need_login || crq->event == IBMVFC_AE_ELS_PLOGI) {
+                               ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
+                               ibmvfc_reinit_host(vhost);
+                       }
                }
-
-               ibmvfc_reinit_host(vhost);
                break;
        case IBMVFC_AE_LINK_DOWN:
        case IBMVFC_AE_ADAPTER_FAILED:
@@ -2927,7 +2930,11 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
                break;
        case IBMVFC_MAD_FAILED:
        default:
-               if (ibmvfc_retry_cmd(rsp->status, rsp->error))
+               if ((rsp->status & IBMVFC_VIOS_FAILURE) && rsp->error == IBMVFC_PLOGI_REQUIRED)
+                       level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi);
+               else if (tgt->logo_rcvd)
+                       level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi);
+               else if (ibmvfc_retry_cmd(rsp->status, rsp->error))
                        level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
                else
                        ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
@@ -3054,6 +3061,7 @@ static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt)
                return;
 
        kref_get(&tgt->kref);
+       tgt->logo_rcvd = 0;
        evt = ibmvfc_get_event(vhost);
        vhost->discovery_threads++;
        ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
index c2668d7d67f5308cdfc33819f0333e719f842947..007fa1c9ef14eedbab72484577bb5683fe9dda19 100644 (file)
@@ -605,6 +605,7 @@ struct ibmvfc_target {
        int need_login;
        int add_rport;
        int init_retries;
+       int logo_rcvd;
        u32 cancel_key;
        struct ibmvfc_service_parms service_parms;
        struct ibmvfc_service_parms service_parms_change;