|
@@ -1516,7 +1516,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
|
|
|
uint32_t rc, keepDID = 0;
|
|
|
int put_node;
|
|
|
int put_rport;
|
|
|
- struct lpfc_node_rrqs rrq;
|
|
|
+ unsigned long *active_rrqs_xri_bitmap = NULL;
|
|
|
|
|
|
/* Fabric nodes can have the same WWPN so we don't bother searching
|
|
|
* by WWPN. Just return the ndlp that was given to us.
|
|
@@ -1534,7 +1534,13 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
|
|
|
|
|
|
if (new_ndlp == ndlp && NLP_CHK_NODE_ACT(new_ndlp))
|
|
|
return ndlp;
|
|
|
- memset(&rrq.xri_bitmap, 0, sizeof(new_ndlp->active_rrqs.xri_bitmap));
|
|
|
+ if (phba->sli_rev == LPFC_SLI_REV4) {
|
|
|
+ active_rrqs_xri_bitmap = mempool_alloc(phba->active_rrq_pool,
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (active_rrqs_xri_bitmap)
|
|
|
+ memset(active_rrqs_xri_bitmap, 0,
|
|
|
+ phba->cfg_rrq_xri_bitmap_sz);
|
|
|
+ }
|
|
|
|
|
|
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
|
|
"3178 PLOGI confirm: ndlp %p x%x: new_ndlp %p\n",
|
|
@@ -1543,41 +1549,58 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
|
|
|
if (!new_ndlp) {
|
|
|
rc = memcmp(&ndlp->nlp_portname, name,
|
|
|
sizeof(struct lpfc_name));
|
|
|
- if (!rc)
|
|
|
+ if (!rc) {
|
|
|
+ if (active_rrqs_xri_bitmap)
|
|
|
+ mempool_free(active_rrqs_xri_bitmap,
|
|
|
+ phba->active_rrq_pool);
|
|
|
return ndlp;
|
|
|
+ }
|
|
|
new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
|
|
|
- if (!new_ndlp)
|
|
|
+ if (!new_ndlp) {
|
|
|
+ if (active_rrqs_xri_bitmap)
|
|
|
+ mempool_free(active_rrqs_xri_bitmap,
|
|
|
+ phba->active_rrq_pool);
|
|
|
return ndlp;
|
|
|
+ }
|
|
|
lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
|
|
|
} else if (!NLP_CHK_NODE_ACT(new_ndlp)) {
|
|
|
rc = memcmp(&ndlp->nlp_portname, name,
|
|
|
sizeof(struct lpfc_name));
|
|
|
- if (!rc)
|
|
|
+ if (!rc) {
|
|
|
+ if (active_rrqs_xri_bitmap)
|
|
|
+ mempool_free(active_rrqs_xri_bitmap,
|
|
|
+ phba->active_rrq_pool);
|
|
|
return ndlp;
|
|
|
+ }
|
|
|
new_ndlp = lpfc_enable_node(vport, new_ndlp,
|
|
|
NLP_STE_UNUSED_NODE);
|
|
|
- if (!new_ndlp)
|
|
|
+ if (!new_ndlp) {
|
|
|
+ if (active_rrqs_xri_bitmap)
|
|
|
+ mempool_free(active_rrqs_xri_bitmap,
|
|
|
+ phba->active_rrq_pool);
|
|
|
return ndlp;
|
|
|
+ }
|
|
|
keepDID = new_ndlp->nlp_DID;
|
|
|
- if (phba->sli_rev == LPFC_SLI_REV4)
|
|
|
- memcpy(&rrq.xri_bitmap,
|
|
|
- &new_ndlp->active_rrqs.xri_bitmap,
|
|
|
- sizeof(new_ndlp->active_rrqs.xri_bitmap));
|
|
|
+ if ((phba->sli_rev == LPFC_SLI_REV4) && active_rrqs_xri_bitmap)
|
|
|
+ memcpy(active_rrqs_xri_bitmap,
|
|
|
+ new_ndlp->active_rrqs_xri_bitmap,
|
|
|
+ phba->cfg_rrq_xri_bitmap_sz);
|
|
|
} else {
|
|
|
keepDID = new_ndlp->nlp_DID;
|
|
|
- if (phba->sli_rev == LPFC_SLI_REV4)
|
|
|
- memcpy(&rrq.xri_bitmap,
|
|
|
- &new_ndlp->active_rrqs.xri_bitmap,
|
|
|
- sizeof(new_ndlp->active_rrqs.xri_bitmap));
|
|
|
+ if (phba->sli_rev == LPFC_SLI_REV4 &&
|
|
|
+ active_rrqs_xri_bitmap)
|
|
|
+ memcpy(active_rrqs_xri_bitmap,
|
|
|
+ new_ndlp->active_rrqs_xri_bitmap,
|
|
|
+ phba->cfg_rrq_xri_bitmap_sz);
|
|
|
}
|
|
|
|
|
|
lpfc_unreg_rpi(vport, new_ndlp);
|
|
|
new_ndlp->nlp_DID = ndlp->nlp_DID;
|
|
|
new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
|
|
|
if (phba->sli_rev == LPFC_SLI_REV4)
|
|
|
- memcpy(new_ndlp->active_rrqs.xri_bitmap,
|
|
|
- &ndlp->active_rrqs.xri_bitmap,
|
|
|
- sizeof(ndlp->active_rrqs.xri_bitmap));
|
|
|
+ memcpy(new_ndlp->active_rrqs_xri_bitmap,
|
|
|
+ ndlp->active_rrqs_xri_bitmap,
|
|
|
+ phba->cfg_rrq_xri_bitmap_sz);
|
|
|
|
|
|
if (ndlp->nlp_flag & NLP_NPR_2B_DISC)
|
|
|
new_ndlp->nlp_flag |= NLP_NPR_2B_DISC;
|
|
@@ -1619,10 +1642,11 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
|
|
|
|
|
|
/* Two ndlps cannot have the same did on the nodelist */
|
|
|
ndlp->nlp_DID = keepDID;
|
|
|
- if (phba->sli_rev == LPFC_SLI_REV4)
|
|
|
- memcpy(&ndlp->active_rrqs.xri_bitmap,
|
|
|
- &rrq.xri_bitmap,
|
|
|
- sizeof(ndlp->active_rrqs.xri_bitmap));
|
|
|
+ if (phba->sli_rev == LPFC_SLI_REV4 &&
|
|
|
+ active_rrqs_xri_bitmap)
|
|
|
+ memcpy(ndlp->active_rrqs_xri_bitmap,
|
|
|
+ active_rrqs_xri_bitmap,
|
|
|
+ phba->cfg_rrq_xri_bitmap_sz);
|
|
|
lpfc_drop_node(vport, ndlp);
|
|
|
}
|
|
|
else {
|
|
@@ -1634,10 +1658,11 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
|
|
|
|
|
|
/* Two ndlps cannot have the same did */
|
|
|
ndlp->nlp_DID = keepDID;
|
|
|
- if (phba->sli_rev == LPFC_SLI_REV4)
|
|
|
- memcpy(&ndlp->active_rrqs.xri_bitmap,
|
|
|
- &rrq.xri_bitmap,
|
|
|
- sizeof(ndlp->active_rrqs.xri_bitmap));
|
|
|
+ if (phba->sli_rev == LPFC_SLI_REV4 &&
|
|
|
+ active_rrqs_xri_bitmap)
|
|
|
+ memcpy(ndlp->active_rrqs_xri_bitmap,
|
|
|
+ active_rrqs_xri_bitmap,
|
|
|
+ phba->cfg_rrq_xri_bitmap_sz);
|
|
|
|
|
|
/* Since we are swapping the ndlp passed in with the new one
|
|
|
* and the did has already been swapped, copy over state.
|
|
@@ -1668,6 +1693,10 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
|
|
|
put_device(&rport->dev);
|
|
|
}
|
|
|
}
|
|
|
+ if (phba->sli_rev == LPFC_SLI_REV4 &&
|
|
|
+ active_rrqs_xri_bitmap)
|
|
|
+ mempool_free(active_rrqs_xri_bitmap,
|
|
|
+ phba->active_rrq_pool);
|
|
|
return new_ndlp;
|
|
|
}
|
|
|
|
|
@@ -2772,6 +2801,7 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
|
|
/* This will cause the callback-function lpfc_cmpl_els_cmd to
|
|
|
* trigger the release of node.
|
|
|
*/
|
|
|
+
|
|
|
lpfc_nlp_put(ndlp);
|
|
|
return 0;
|
|
|
}
|