diff options
author | James Smart <james.smart@emulex.com> | 2015-04-07 15:07:11 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Odin.com> | 2015-04-10 10:45:54 -0400 |
commit | ed4afe7405f3839236fd34c7918204640c00e4e8 (patch) | |
tree | 4d55fd687ef9df4f31a51ab0a02c173e35094ef4 /drivers/scsi | |
parent | c63779702094bcfdb2ead17181fbcd04b71b0215 (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.c | 27 |
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 */ |