[SCSI] lpfc 8.2.5 : Miscellaneous Fixes
authorJames Smart <James.Smart@Emulex.Com>
Fri, 8 Feb 2008 23:49:39 +0000 (18:49 -0500)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Mon, 11 Feb 2008 23:52:57 +0000 (17:52 -0600)
Miscellaneous fixes:
- Fix ERRATT flag which was overlapping
- Allow RESTART mbx commands through when stopped.
- Accept incoming PLOGI when connected to an N_Port.
- Fix NPort to NPort pt2pt problems: ADISC and reg_vpi issues
- Fix vport unloading error that erroneously cleaned up RSCN buffers
- Fix memory leak during repeated unloads - in mbox handling
- Fix link bounce vs FLOGI race conditions

Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_sli.c

index 572c525..cbe07d7 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2007 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2008 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -409,7 +409,7 @@ struct lpfc_hba {
                                        /* This flag is set while issuing */
                                        /* INIT_LINK mailbox command */
 #define LS_NPIV_FAB_SUPPORTED 0x2      /* Fabric supports NPIV */
-#define LS_IGNORE_ERATT       0x3      /* intr handler should ignore ERATT */
+#define LS_IGNORE_ERATT       0x4      /* intr handler should ignore ERATT */
 
        struct lpfc_sli2_slim *slim2p;
        struct lpfc_dmabuf hbqslimp;
index ef061d9..fc48e40 100644 (file)
@@ -1946,11 +1946,13 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
                }
 
                /* If HBA encountered an error attention, allow only DUMP
-                * mailbox command until the HBA is restarted.
+                * or RESTART mailbox commands until the HBA is restarted.
                 */
                if ((phba->pport->stopped) &&
-                       (phba->sysfs_mbox.mbox->mb.mbxCommand
-                               != MBX_DUMP_MEMORY)) {
+                       (phba->sysfs_mbox.mbox->mb.mbxCommand !=
+                               MBX_DUMP_MEMORY &&
+                        phba->sysfs_mbox.mbox->mb.mbxCommand !=
+                               MBX_RESTART)) {
                        sysfs_mbox_idle(phba);
                        spin_unlock_irq(&phba->hbalock);
                        return -EPERM;
index 39268e6..60afc80 100644 (file)
@@ -2046,7 +2046,8 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                retry = 1;
 
        if ((cmd == ELS_CMD_FLOGI) &&
-           (phba->fc_topology != TOPOLOGY_LOOP)) {
+           (phba->fc_topology != TOPOLOGY_LOOP) &&
+           !lpfc_error_lost_link(irsp)) {
                /* FLOGI retry policy */
                retry = 1;
                maxretry = 48;
@@ -4091,8 +4092,15 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp);
 
                if (vport->port_state < LPFC_DISC_AUTH) {
-                       rjt_err = LSRJT_UNABLE_TPC;
-                       break;
+                       if (!(phba->pport->fc_flag & FC_PT2PT) ||
+                               (phba->pport->fc_flag & FC_PT2PT_PLOGI)) {
+                               rjt_err = LSRJT_UNABLE_TPC;
+                               break;
+                       }
+                       /* We get here, and drop thru, if we are PT2PT with
+                        * another NPort and the other side has initiated
+                        * the PLOGI before responding to our FLOGI.
+                        */
                }
 
                shost = lpfc_shost_from_vport(vport);
index 1ee3e62..2589267 100644 (file)
@@ -800,21 +800,9 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        writel(control, phba->HCregaddr);
        readl(phba->HCregaddr); /* flush */
        spin_unlock_irq(&phba->hbalock);
+       mempool_free(pmb, phba->mbox_mem_pool);
        return;
 
-       vport->num_disc_nodes = 0;
-       /* go thru NPR nodes and issue ELS PLOGIs */
-       if (vport->fc_npr_cnt)
-               lpfc_els_disc_plogi(vport);
-
-       if (!vport->num_disc_nodes) {
-               spin_lock_irq(shost->host_lock);
-               vport->fc_flag &= ~FC_NDISC_ACTIVE;
-               spin_unlock_irq(shost->host_lock);
-       }
-
-       vport->port_state = LPFC_VPORT_READY;
-
 out:
        /* Device Discovery completes */
        lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
@@ -2484,6 +2472,7 @@ lpfc_disc_start(struct lpfc_vport *vport)
         * continue discovery.
         */
        if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
+           !(vport->fc_flag & FC_PT2PT) &&
            !(vport->fc_flag & FC_RSCN_MODE)) {
                lpfc_issue_reg_vpi(phba, vport);
                return;
index e0363be..9914154 100644 (file)
@@ -461,12 +461,21 @@ lpfc_config_port_post(struct lpfc_hba *phba)
 int
 lpfc_hba_down_prep(struct lpfc_hba *phba)
 {
+       struct lpfc_vport **vports;
+       int i;
        /* Disable interrupts */
        writel(0, phba->HCregaddr);
        readl(phba->HCregaddr); /* flush */
 
-       lpfc_cleanup_discovery_resources(phba->pport);
-       return 0;
+       if (phba->pport->load_flag & FC_UNLOADING)
+               lpfc_cleanup_discovery_resources(phba->pport);
+       else {
+               vports = lpfc_create_vport_work_array(phba);
+               if (vports != NULL)
+                       for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++)
+                               lpfc_cleanup_discovery_resources(vports[i]);
+               lpfc_destroy_vport_work_array(phba, vports);
+       }       return 0;
 }
 
 /************************************************************************/
index 01d5483..d513813 100644 (file)
@@ -645,13 +645,15 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
                return 0;
        }
 
-       /* Check config parameter use-adisc or FCP-2 */
-       if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) ||
-           ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) {
-               spin_lock_irq(shost->host_lock);
-               ndlp->nlp_flag |= NLP_NPR_ADISC;
-               spin_unlock_irq(shost->host_lock);
-               return 1;
+       if (!(vport->fc_flag & FC_PT2PT)) {
+               /* Check config parameter use-adisc or FCP-2 */
+               if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) ||
+                   ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) {
+                       spin_lock_irq(shost->host_lock);
+                       ndlp->nlp_flag |= NLP_NPR_ADISC;
+                       spin_unlock_irq(shost->host_lock);
+                       return 1;
+               }
        }
        ndlp->nlp_flag &= ~NLP_NPR_ADISC;
        lpfc_unreg_rpi(vport, ndlp);
index fdd01e3..456b8ec 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2007 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2008 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -2404,9 +2404,7 @@ lpfc_do_config_port(struct lpfc_hba *phba, int sli_mode)
        if ((pmb->mb.un.varCfgPort.sli_mode == 3) &&
                (!pmb->mb.un.varCfgPort.cMA)) {
                rc = -ENXIO;
-               goto do_prep_failed;
        }
-       return rc;
 
 do_prep_failed:
        mempool_free(pmb, phba->mbox_mem_pool);