aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2015-04-07 15:07:11 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-04-10 10:45:54 -0400
commited4afe7405f3839236fd34c7918204640c00e4e8 (patch)
tree4d55fd687ef9df4f31a51ab0a02c173e35094ef4 /drivers/scsi
parentc63779702094bcfdb2ead17181fbcd04b71b0215 (diff)
lpfc: Fix to handle PLOGI when already logged in
Signed-off-by: Dick Kennedy <dick.kennedy@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 5cc1103d811e..3d933633426c 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -276,6 +276,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
276 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 276 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
277 struct lpfc_hba *phba = vport->phba; 277 struct lpfc_hba *phba = vport->phba;
278 struct lpfc_dmabuf *pcmd; 278 struct lpfc_dmabuf *pcmd;
279 uint64_t nlp_portwwn = 0;
279 uint32_t *lp; 280 uint32_t *lp;
280 IOCB_t *icmd; 281 IOCB_t *icmd;
281 struct serv_parm *sp; 282 struct serv_parm *sp;
@@ -332,6 +333,8 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
332 NULL); 333 NULL);
333 return 0; 334 return 0;
334 } 335 }
336
337 nlp_portwwn = wwn_to_u64(ndlp->nlp_portname.u.wwn);
335 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0) == 0)) { 338 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0) == 0)) {
336 /* Reject this request because invalid parameters */ 339 /* Reject this request because invalid parameters */
337 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; 340 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
@@ -367,7 +370,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
367 ndlp->nlp_maxframe = 370 ndlp->nlp_maxframe =
368 ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; 371 ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
369 372
370 /* no need to reg_login if we are already in one of these states */ 373 /* if already logged in, do implicit logout */
371 switch (ndlp->nlp_state) { 374 switch (ndlp->nlp_state) {
372 case NLP_STE_NPR_NODE: 375 case NLP_STE_NPR_NODE:
373 if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) 376 if (!(ndlp->nlp_flag & NLP_NPR_ADISC))
@@ -376,8 +379,26 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
376 case NLP_STE_PRLI_ISSUE: 379 case NLP_STE_PRLI_ISSUE:
377 case NLP_STE_UNMAPPED_NODE: 380 case NLP_STE_UNMAPPED_NODE:
378 case NLP_STE_MAPPED_NODE: 381 case NLP_STE_MAPPED_NODE:
379 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL); 382 /* lpfc_plogi_confirm_nport skips fabric did, handle it here */
380 return 1; 383 if (!(ndlp->nlp_type & NLP_FABRIC)) {
384 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
385 ndlp, NULL);
386 return 1;
387 }
388 if (nlp_portwwn != 0 &&
389 nlp_portwwn != wwn_to_u64(sp->portName.u.wwn))
390 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
391 "0143 PLOGI recv'd from DID: x%x "
392 "WWPN changed: old %llx new %llx\n",
393 ndlp->nlp_DID,
394 (unsigned long long)nlp_portwwn,
395 (unsigned long long)
396 wwn_to_u64(sp->portName.u.wwn));
397
398 ndlp->nlp_prev_state = ndlp->nlp_state;
399 /* rport needs to be unregistered first */
400 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
401 break;
381 } 402 }
382 403
383 /* Check for Nport to NPort pt2pt protocol */ 404 /* Check for Nport to NPort pt2pt protocol */