Merge ../linus
[pandora-kernel.git] / drivers / scsi / lpfc / lpfc_nportdisc.c
index 27d60ad..20449a8 100644 (file)
@@ -179,7 +179,7 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 
        /* Abort outstanding I/O on NPort <nlp_DID> */
        lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
-                       "%d:0201 Abort outstanding I/O on NPort x%x "
+                       "%d:0205 Abort outstanding I/O on NPort x%x "
                        "Data: x%x x%x x%x\n",
                        phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag,
                        ndlp->nlp_state, ndlp->nlp_rpi);
@@ -393,6 +393,20 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
        mbox->context2  = ndlp;
        ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);
 
+       /*
+        * If there is an outstanding PLOGI issued, abort it before
+        * sending ACC rsp for received PLOGI. If pending plogi
+        * is not canceled here, the plogi will be rejected by
+        * remote port and will be retried. On a configuration with
+        * single discovery thread, this will cause a huge delay in
+        * discovery. Also this will cause multiple state machines
+        * running in parallel for this node.
+        */
+       if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) {
+               /* software abort outstanding PLOGI */
+               lpfc_els_abort(phba, ndlp, 1);
+       }
+
        lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0);
        return 1;
 
@@ -1110,6 +1124,17 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
                                phba->brd_no,
                                did, mb->mbxStatus, phba->hba_state);
 
+               /*
+                * If RegLogin failed due to lack of HBA resources do not
+                * retry discovery.
+                */
+               if (mb->mbxStatus == MBXERR_RPI_FULL) {
+                       ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
+                       ndlp->nlp_state = NLP_STE_UNUSED_NODE;
+                       lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
+                       return ndlp->nlp_state;
+               }
+
                /* Put ndlp in npr list set plogi timer for 1 sec */
                mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
                spin_lock_irq(phba->host->host_lock);
@@ -1590,7 +1615,13 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba,
 
        lpfc_rcv_padisc(phba, ndlp, cmdiocb);
 
-       if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
+       /*
+        * Do not start discovery if discovery is about to start
+        * or discovery in progress for this node. Starting discovery
+        * here will affect the counting of discovery threads.
+        */
+       if ((!(ndlp->nlp_flag & NLP_DELAY_TMO)) &&
+               (ndlp->nlp_flag & NLP_NPR_2B_DISC)){
                if (ndlp->nlp_flag & NLP_NPR_ADISC) {
                        ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
                        ndlp->nlp_state = NLP_STE_ADISC_ISSUE;