]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Fix for driver using duplicate RPIs after LPe16000 port reset (CR 126723)
authorVaios Papadimitriou <vaios.papadimitriou@emulex.com>
Tue, 8 May 2012 22:01:25 +0000 (17:01 -0500)
committerMaxim Uvarov <maxim.uvarov@oracle.com>
Wed, 9 May 2012 00:01:25 +0000 (17:01 -0700)
The RPI bit map is reinitiatized in the adapter port 'online' path. SLI4 RPI are
designed to be 'long lived', so when the adapter port is taken offline, the
driver will reuse the RPI if the port is recovered within devloss tmo.
These stale RPI values can collide when new RPIs are allocated. We now free RPIs
on all active nodes and then allocate new RPIs

commit id: 6b5151fd7baec6812fece993ddd7a2cf9fd0125f

Signed-off-by: Maxim Uvarov <maxim.uvarov@oracle.com>
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli.c

index e159489a1a007e39e02aecd95eda7a09777cf3b0..63759d7ee5c32a1e2408f7331664a3021ae418da 100644 (file)
@@ -462,3 +462,4 @@ int lpfc_issue_unreg_vfi(struct lpfc_vport *);
 int lpfc_selective_reset(struct lpfc_hba *);
 int lpfc_sli4_read_config(struct lpfc_hba *phba);
 int lpfc_scsi_buf_update(struct lpfc_hba *phba);
+void lpfc_sli4_node_prep(struct lpfc_hba *phba);
index 5f41787b9c4f6ea1ba436d716bc99f82d40c75e5..b1af6624b94f005a7de809d85e1851aa18e1982c 100644 (file)
@@ -2501,6 +2501,42 @@ lpfc_block_mgmt_io(struct lpfc_hba * phba)
        }
 }
 
+/**
+ * lpfc_sli4_node_prep - Assign RPIs for active nodes.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * Allocate RPIs for all active remote nodes. This is needed whenever
+ * an SLI4 adapter is reset and the driver is not unloading. Its purpose
+ * is to fixup the temporary rpi assignments.
+ **/
+void
+lpfc_sli4_node_prep(struct lpfc_hba *phba)
+{
+       struct lpfc_nodelist  *ndlp, *next_ndlp;
+       struct lpfc_vport **vports;
+       int i;
+
+       if (phba->sli_rev != LPFC_SLI_REV4)
+               return;
+
+       vports = lpfc_create_vport_work_array(phba);
+       if (vports != NULL) {
+               for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
+                       if (vports[i]->load_flag & FC_UNLOADING)
+                               continue;
+
+                       list_for_each_entry_safe(ndlp, next_ndlp,
+                                                &vports[i]->fc_nodes,
+                                                nlp_listp) {
+                               if (NLP_CHK_NODE_ACT(ndlp))
+                                       ndlp->nlp_rpi =
+                                               lpfc_sli4_alloc_rpi(phba);
+                       }
+               }
+       }
+       lpfc_destroy_vport_work_array(phba, vports);
+}
+
 /**
  * lpfc_online - Initialize and bring a HBA online
  * @phba: pointer to lpfc hba data structure.
@@ -2642,6 +2678,15 @@ lpfc_offline_prep(struct lpfc_hba * phba)
                                }
                                spin_lock_irq(shost->host_lock);
                                ndlp->nlp_flag &= ~NLP_NPR_ADISC;
+
+                               /*
+                                * Whenever an SLI4 port goes offline, free the
+                                * RPI.  A new RPI when the adapter port comes 
+                                * back online.
+                                */
+                               if (phba->sli_rev == LPFC_SLI_REV4)
+                                       lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi);
+
                                spin_unlock_irq(shost->host_lock);
                                lpfc_unreg_rpi(vports[i], ndlp);
                        }
index c80bce633ae15b9169ff000b864c2cdfa057efe0..d1d23eed74006020a51decf48af189e8dbe67391 100644 (file)
@@ -5600,6 +5600,8 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba)
                for (i = 0; i < count; i++)
                        phba->sli4_hba.rpi_ids[i] = base + i;
 
+               lpfc_sli4_node_prep(phba);
+
                /* VPIs. */
                count = phba->sli4_hba.max_cfg_param.max_vpi;
                base = phba->sli4_hba.max_cfg_param.vpi_base;