|
@@ -648,33 +648,32 @@ lpfc_more_plogi(struct lpfc_hba * phba)
|
|
}
|
|
}
|
|
|
|
|
|
static struct lpfc_nodelist *
|
|
static struct lpfc_nodelist *
|
|
-lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
|
|
|
|
|
|
+lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp,
|
|
struct lpfc_nodelist *ndlp)
|
|
struct lpfc_nodelist *ndlp)
|
|
{
|
|
{
|
|
struct lpfc_nodelist *new_ndlp;
|
|
struct lpfc_nodelist *new_ndlp;
|
|
- struct lpfc_dmabuf *pcmd, *prsp;
|
|
|
|
uint32_t *lp;
|
|
uint32_t *lp;
|
|
struct serv_parm *sp;
|
|
struct serv_parm *sp;
|
|
uint8_t name[sizeof (struct lpfc_name)];
|
|
uint8_t name[sizeof (struct lpfc_name)];
|
|
uint32_t rc;
|
|
uint32_t rc;
|
|
|
|
|
|
- pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
|
|
|
|
- prsp = (struct lpfc_dmabuf *) pcmd->list.next;
|
|
|
|
lp = (uint32_t *) prsp->virt;
|
|
lp = (uint32_t *) prsp->virt;
|
|
sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
|
|
sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
|
|
|
|
+ memset(name, 0, sizeof (struct lpfc_name));
|
|
|
|
|
|
/* Now we to find out if the NPort we are logging into, matches the WWPN
|
|
/* Now we to find out if the NPort we are logging into, matches the WWPN
|
|
* we have for that ndlp. If not, we have some work to do.
|
|
* we have for that ndlp. If not, we have some work to do.
|
|
*/
|
|
*/
|
|
new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName);
|
|
new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName);
|
|
|
|
|
|
- memset(name, 0, sizeof (struct lpfc_name));
|
|
|
|
- rc = memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name));
|
|
|
|
- if (!rc || (new_ndlp == ndlp)) {
|
|
|
|
|
|
+ if (new_ndlp == ndlp)
|
|
return ndlp;
|
|
return ndlp;
|
|
- }
|
|
|
|
|
|
|
|
if (!new_ndlp) {
|
|
if (!new_ndlp) {
|
|
|
|
+ rc =
|
|
|
|
+ memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name));
|
|
|
|
+ if (!rc)
|
|
|
|
+ return ndlp;
|
|
new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
|
|
new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
|
|
if (!new_ndlp)
|
|
if (!new_ndlp)
|
|
return ndlp;
|
|
return ndlp;
|
|
@@ -683,17 +682,21 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
|
|
}
|
|
}
|
|
|
|
|
|
lpfc_unreg_rpi(phba, new_ndlp);
|
|
lpfc_unreg_rpi(phba, new_ndlp);
|
|
- new_ndlp->nlp_prev_state = ndlp->nlp_state;
|
|
|
|
new_ndlp->nlp_DID = ndlp->nlp_DID;
|
|
new_ndlp->nlp_DID = ndlp->nlp_DID;
|
|
- new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
|
|
|
|
- lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST);
|
|
|
|
|
|
+ new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
|
|
|
|
+ new_ndlp->nlp_state = ndlp->nlp_state;
|
|
|
|
+ lpfc_nlp_list(phba, new_ndlp, ndlp->nlp_flag & NLP_LIST_MASK);
|
|
|
|
|
|
/* Move this back to NPR list */
|
|
/* Move this back to NPR list */
|
|
- lpfc_unreg_rpi(phba, ndlp);
|
|
|
|
- ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
|
|
|
|
- ndlp->nlp_state = NLP_STE_NPR_NODE;
|
|
|
|
- lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
|
|
|
|
-
|
|
|
|
|
|
+ if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) {
|
|
|
|
+ lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ lpfc_unreg_rpi(phba, ndlp);
|
|
|
|
+ ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
|
|
|
|
+ ndlp->nlp_state = NLP_STE_NPR_NODE;
|
|
|
|
+ lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
|
|
|
|
+ }
|
|
return new_ndlp;
|
|
return new_ndlp;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -703,6 +706,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
|
|
{
|
|
{
|
|
IOCB_t *irsp;
|
|
IOCB_t *irsp;
|
|
struct lpfc_nodelist *ndlp;
|
|
struct lpfc_nodelist *ndlp;
|
|
|
|
+ struct lpfc_dmabuf *prsp;
|
|
int disc, rc, did, type;
|
|
int disc, rc, did, type;
|
|
|
|
|
|
|
|
|
|
@@ -769,7 +773,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
/* Good status, call state machine */
|
|
/* Good status, call state machine */
|
|
- ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp);
|
|
|
|
|
|
+ prsp = list_entry(((struct lpfc_dmabuf *)
|
|
|
|
+ cmdiocb->context2)->list.next,
|
|
|
|
+ struct lpfc_dmabuf, list);
|
|
|
|
+ ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp);
|
|
rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb,
|
|
rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb,
|
|
NLP_EVT_CMPL_PLOGI);
|
|
NLP_EVT_CMPL_PLOGI);
|
|
}
|
|
}
|
|
@@ -3441,6 +3448,8 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
|
|
if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) {
|
|
if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) {
|
|
ndlp->nlp_type |= NLP_FABRIC;
|
|
ndlp->nlp_type |= NLP_FABRIC;
|
|
}
|
|
}
|
|
|
|
+ ndlp->nlp_state = NLP_STE_UNUSED_NODE;
|
|
|
|
+ lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
|
|
}
|
|
}
|
|
|
|
|
|
phba->fc_stat.elsRcvFrame++;
|
|
phba->fc_stat.elsRcvFrame++;
|
|
@@ -3462,13 +3471,14 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
|
|
rjt_err = 1;
|
|
rjt_err = 1;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp);
|
|
lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI);
|
|
lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI);
|
|
break;
|
|
break;
|
|
case ELS_CMD_FLOGI:
|
|
case ELS_CMD_FLOGI:
|
|
phba->fc_stat.elsRcvFLOGI++;
|
|
phba->fc_stat.elsRcvFLOGI++;
|
|
lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode);
|
|
lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode);
|
|
if (newnode) {
|
|
if (newnode) {
|
|
- mempool_free( ndlp, phba->nlp_mem_pool);
|
|
|
|
|
|
+ lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case ELS_CMD_LOGO:
|
|
case ELS_CMD_LOGO:
|
|
@@ -3491,7 +3501,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
|
|
phba->fc_stat.elsRcvRSCN++;
|
|
phba->fc_stat.elsRcvRSCN++;
|
|
lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode);
|
|
lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode);
|
|
if (newnode) {
|
|
if (newnode) {
|
|
- mempool_free( ndlp, phba->nlp_mem_pool);
|
|
|
|
|
|
+ lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case ELS_CMD_ADISC:
|
|
case ELS_CMD_ADISC:
|
|
@@ -3534,28 +3544,28 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
|
|
phba->fc_stat.elsRcvLIRR++;
|
|
phba->fc_stat.elsRcvLIRR++;
|
|
lpfc_els_rcv_lirr(phba, elsiocb, ndlp);
|
|
lpfc_els_rcv_lirr(phba, elsiocb, ndlp);
|
|
if (newnode) {
|
|
if (newnode) {
|
|
- mempool_free( ndlp, phba->nlp_mem_pool);
|
|
|
|
|
|
+ lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case ELS_CMD_RPS:
|
|
case ELS_CMD_RPS:
|
|
phba->fc_stat.elsRcvRPS++;
|
|
phba->fc_stat.elsRcvRPS++;
|
|
lpfc_els_rcv_rps(phba, elsiocb, ndlp);
|
|
lpfc_els_rcv_rps(phba, elsiocb, ndlp);
|
|
if (newnode) {
|
|
if (newnode) {
|
|
- mempool_free( ndlp, phba->nlp_mem_pool);
|
|
|
|
|
|
+ lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case ELS_CMD_RPL:
|
|
case ELS_CMD_RPL:
|
|
phba->fc_stat.elsRcvRPL++;
|
|
phba->fc_stat.elsRcvRPL++;
|
|
lpfc_els_rcv_rpl(phba, elsiocb, ndlp);
|
|
lpfc_els_rcv_rpl(phba, elsiocb, ndlp);
|
|
if (newnode) {
|
|
if (newnode) {
|
|
- mempool_free( ndlp, phba->nlp_mem_pool);
|
|
|
|
|
|
+ lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case ELS_CMD_RNID:
|
|
case ELS_CMD_RNID:
|
|
phba->fc_stat.elsRcvRNID++;
|
|
phba->fc_stat.elsRcvRNID++;
|
|
lpfc_els_rcv_rnid(phba, elsiocb, ndlp);
|
|
lpfc_els_rcv_rnid(phba, elsiocb, ndlp);
|
|
if (newnode) {
|
|
if (newnode) {
|
|
- mempool_free( ndlp, phba->nlp_mem_pool);
|
|
|
|
|
|
+ lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
@@ -3567,7 +3577,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
|
|
"%d:0115 Unknown ELS command x%x received from "
|
|
"%d:0115 Unknown ELS command x%x received from "
|
|
"NPORT x%x\n", phba->brd_no, cmd, did);
|
|
"NPORT x%x\n", phba->brd_no, cmd, did);
|
|
if (newnode) {
|
|
if (newnode) {
|
|
- mempool_free( ndlp, phba->nlp_mem_pool);
|
|
|
|
|
|
+ lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
}
|
|
}
|