aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_nportdisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nportdisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c145
1 files changed, 54 insertions, 91 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index d08c4c89074..6688a8689b5 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -235,10 +235,7 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
235 (iocb->iocb_cmpl) (phba, iocb, iocb); 235 (iocb->iocb_cmpl) (phba, iocb, iocb);
236 } 236 }
237 } 237 }
238 238 lpfc_cancel_retry_delay_tmo(phba->pport, ndlp);
239 /* If we are delaying issuing an ELS command, cancel it */
240 if (ndlp->nlp_flag & NLP_DELAY_TMO)
241 lpfc_cancel_retry_delay_tmo(phba->pport, ndlp);
242 return 0; 239 return 0;
243} 240}
244 241
@@ -249,7 +246,6 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
249 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 246 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
250 struct lpfc_hba *phba = vport->phba; 247 struct lpfc_hba *phba = vport->phba;
251 struct lpfc_dmabuf *pcmd; 248 struct lpfc_dmabuf *pcmd;
252 struct lpfc_work_evt *evtp;
253 uint32_t *lp; 249 uint32_t *lp;
254 IOCB_t *icmd; 250 IOCB_t *icmd;
255 struct serv_parm *sp; 251 struct serv_parm *sp;
@@ -425,73 +421,8 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
425 ndlp, mbox); 421 ndlp, mbox);
426 return 1; 422 return 1;
427 } 423 }
428
429 /* If the remote NPort logs into us, before we can initiate
430 * discovery to them, cleanup the NPort from discovery accordingly.
431 */
432 if (ndlp->nlp_state == NLP_STE_NPR_NODE) {
433 spin_lock_irq(shost->host_lock);
434 ndlp->nlp_flag &= ~NLP_DELAY_TMO;
435 spin_unlock_irq(shost->host_lock);
436 del_timer_sync(&ndlp->nlp_delayfunc);
437 ndlp->nlp_last_elscmd = 0;
438
439 if (!list_empty(&ndlp->els_retry_evt.evt_listp)) {
440 list_del_init(&ndlp->els_retry_evt.evt_listp);
441 /* Decrement ndlp reference count held for the
442 * delayed retry
443 */
444 evtp = &ndlp->els_retry_evt;
445 lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1);
446 }
447
448 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
449 spin_lock_irq(shost->host_lock);
450 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
451 spin_unlock_irq(shost->host_lock);
452
453 if ((ndlp->nlp_flag & NLP_ADISC_SND) &&
454 (vport->num_disc_nodes)) {
455 /* Check to see if there are more
456 * ADISCs to be sent
457 */
458 lpfc_more_adisc(vport);
459
460 if ((vport->num_disc_nodes == 0) &&
461 (vport->fc_npr_cnt))
462 lpfc_els_disc_plogi(vport);
463
464 if (vport->num_disc_nodes == 0) {
465 spin_lock_irq(shost->host_lock);
466 vport->fc_flag &= ~FC_NDISC_ACTIVE;
467 spin_unlock_irq(shost->host_lock);
468 lpfc_can_disctmo(vport);
469 lpfc_end_rscn(vport);
470 }
471 }
472 }
473 } else if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) &&
474 (ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
475 (vport->num_disc_nodes)) {
476 spin_lock_irq(shost->host_lock);
477 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
478 spin_unlock_irq(shost->host_lock);
479 /* Check to see if there are more
480 * PLOGIs to be sent
481 */
482 lpfc_more_plogi(vport);
483 if (vport->num_disc_nodes == 0) {
484 spin_lock_irq(shost->host_lock);
485 vport->fc_flag &= ~FC_NDISC_ACTIVE;
486 spin_unlock_irq(shost->host_lock);
487 lpfc_can_disctmo(vport);
488 lpfc_end_rscn(vport);
489 }
490 }
491
492 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox); 424 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox);
493 return 1; 425 return 1;
494
495out: 426out:
496 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; 427 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
497 stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; 428 stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE;
@@ -574,7 +505,9 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
574 else 505 else
575 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); 506 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
576 507
577 if (!(ndlp->nlp_type & NLP_FABRIC) || 508 if ((!(ndlp->nlp_type & NLP_FABRIC) &&
509 ((ndlp->nlp_type & NLP_FCP_TARGET) ||
510 !(ndlp->nlp_type & NLP_FCP_INITIATOR))) ||
578 (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { 511 (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
579 /* Only try to re-login if this is NOT a Fabric Node */ 512 /* Only try to re-login if this is NOT a Fabric Node */
580 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); 513 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
@@ -751,6 +684,7 @@ static uint32_t
751lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 684lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
752 void *arg, uint32_t evt) 685 void *arg, uint32_t evt)
753{ 686{
687 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
754 struct lpfc_hba *phba = vport->phba; 688 struct lpfc_hba *phba = vport->phba;
755 struct lpfc_iocbq *cmdiocb = arg; 689 struct lpfc_iocbq *cmdiocb = arg;
756 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; 690 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
@@ -776,7 +710,22 @@ lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
776 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, 710 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
777 NULL); 711 NULL);
778 } else { 712 } else {
779 lpfc_rcv_plogi(vport, ndlp, cmdiocb); 713 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb) &&
714 (ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
715 (vport->num_disc_nodes)) {
716 spin_lock_irq(shost->host_lock);
717 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
718 spin_unlock_irq(shost->host_lock);
719 /* Check if there are more PLOGIs to be sent */
720 lpfc_more_plogi(vport);
721 if (vport->num_disc_nodes == 0) {
722 spin_lock_irq(shost->host_lock);
723 vport->fc_flag &= ~FC_NDISC_ACTIVE;
724 spin_unlock_irq(shost->host_lock);
725 lpfc_can_disctmo(vport);
726 lpfc_end_rscn(vport);
727 }
728 }
780 } /* If our portname was less */ 729 } /* If our portname was less */
781 730
782 return ndlp->nlp_state; 731 return ndlp->nlp_state;
@@ -1040,6 +989,7 @@ static uint32_t
1040lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 989lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1041 void *arg, uint32_t evt) 990 void *arg, uint32_t evt)
1042{ 991{
992 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1043 struct lpfc_hba *phba = vport->phba; 993 struct lpfc_hba *phba = vport->phba;
1044 struct lpfc_iocbq *cmdiocb; 994 struct lpfc_iocbq *cmdiocb;
1045 995
@@ -1048,9 +998,28 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1048 998
1049 cmdiocb = (struct lpfc_iocbq *) arg; 999 cmdiocb = (struct lpfc_iocbq *) arg;
1050 1000
1051 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) 1001 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
1052 return ndlp->nlp_state; 1002 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1003 spin_lock_irq(shost->host_lock);
1004 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1005 spin_unlock_irq(shost->host_lock);
1053 1006
1007 if (vport->num_disc_nodes) {
1008 lpfc_more_adisc(vport);
1009 if ((vport->num_disc_nodes == 0) &&
1010 (vport->fc_npr_cnt))
1011 lpfc_els_disc_plogi(vport);
1012 if (vport->num_disc_nodes == 0) {
1013 spin_lock_irq(shost->host_lock);
1014 vport->fc_flag &= ~FC_NDISC_ACTIVE;
1015 spin_unlock_irq(shost->host_lock);
1016 lpfc_can_disctmo(vport);
1017 lpfc_end_rscn(vport);
1018 }
1019 }
1020 }
1021 return ndlp->nlp_state;
1022 }
1054 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; 1023 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1055 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); 1024 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
1056 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); 1025 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
@@ -1742,24 +1711,21 @@ lpfc_rcv_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1742 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; 1711 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1743 1712
1744 /* Ignore PLOGI if we have an outstanding LOGO */ 1713 /* Ignore PLOGI if we have an outstanding LOGO */
1745 if (ndlp->nlp_flag & (NLP_LOGO_SND | NLP_LOGO_ACC)) { 1714 if (ndlp->nlp_flag & (NLP_LOGO_SND | NLP_LOGO_ACC))
1746 return ndlp->nlp_state; 1715 return ndlp->nlp_state;
1747 }
1748
1749 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) { 1716 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
1717 lpfc_cancel_retry_delay_tmo(vport, ndlp);
1750 spin_lock_irq(shost->host_lock); 1718 spin_lock_irq(shost->host_lock);
1751 ndlp->nlp_flag &= ~NLP_NPR_ADISC; 1719 ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC);
1752 spin_unlock_irq(shost->host_lock); 1720 spin_unlock_irq(shost->host_lock);
1753 return ndlp->nlp_state; 1721 } else if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
1754 } 1722 /* send PLOGI immediately, move to PLOGI issue state */
1755 1723 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
1756 /* send PLOGI immediately, move to PLOGI issue state */ 1724 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
1757 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { 1725 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
1758 ndlp->nlp_prev_state = NLP_STE_NPR_NODE; 1726 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
1759 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); 1727 }
1760 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
1761 } 1728 }
1762
1763 return ndlp->nlp_state; 1729 return ndlp->nlp_state;
1764} 1730}
1765 1731
@@ -1810,7 +1776,6 @@ lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1810 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; 1776 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1811 1777
1812 lpfc_rcv_padisc(vport, ndlp, cmdiocb); 1778 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
1813
1814 /* 1779 /*
1815 * Do not start discovery if discovery is about to start 1780 * Do not start discovery if discovery is about to start
1816 * or discovery in progress for this node. Starting discovery 1781 * or discovery in progress for this node. Starting discovery
@@ -1973,9 +1938,7 @@ lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1973 spin_lock_irq(shost->host_lock); 1938 spin_lock_irq(shost->host_lock);
1974 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); 1939 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1975 spin_unlock_irq(shost->host_lock); 1940 spin_unlock_irq(shost->host_lock);
1976 if (ndlp->nlp_flag & NLP_DELAY_TMO) { 1941 lpfc_cancel_retry_delay_tmo(vport, ndlp);
1977 lpfc_cancel_retry_delay_tmo(vport, ndlp);
1978 }
1979 return ndlp->nlp_state; 1942 return ndlp->nlp_state;
1980} 1943}
1981 1944