aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c15
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c20
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c56
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c15
7 files changed, 105 insertions, 5 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 5087c4211b4..fbc9baeb604 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -65,6 +65,7 @@ void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
65void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); 65void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
66void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *); 66void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *);
67void lpfc_retry_pport_discovery(struct lpfc_hba *); 67void lpfc_retry_pport_discovery(struct lpfc_hba *);
68void lpfc_release_rpi(struct lpfc_hba *, struct lpfc_vport *, uint16_t);
68 69
69void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); 70void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
70void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *); 71void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *);
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 2851d75ffc6..36257a68550 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -38,6 +38,7 @@ enum lpfc_work_type {
38 LPFC_EVT_ELS_RETRY, 38 LPFC_EVT_ELS_RETRY,
39 LPFC_EVT_DEV_LOSS, 39 LPFC_EVT_DEV_LOSS,
40 LPFC_EVT_FASTPATH_MGMT_EVT, 40 LPFC_EVT_FASTPATH_MGMT_EVT,
41 LPFC_EVT_RESET_HBA,
41}; 42};
42 43
43/* structure used to queue event to the discovery tasklet */ 44/* structure used to queue event to the discovery tasklet */
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 1de60ce6f29..c4c7f0ad746 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -584,6 +584,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
584 spin_unlock_irq(shost->host_lock); 584 spin_unlock_irq(shost->host_lock);
585 lpfc_unreg_rpi(vport, np); 585 lpfc_unreg_rpi(vport, np);
586 } 586 }
587 lpfc_cleanup_pending_mbox(vport);
587 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { 588 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
588 lpfc_mbx_unreg_vpi(vport); 589 lpfc_mbx_unreg_vpi(vport);
589 spin_lock_irq(shost->host_lock); 590 spin_lock_irq(shost->host_lock);
@@ -6316,6 +6317,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6316 spin_unlock_irq(shost->host_lock); 6317 spin_unlock_irq(shost->host_lock);
6317 lpfc_unreg_rpi(vport, np); 6318 lpfc_unreg_rpi(vport, np);
6318 } 6319 }
6320 lpfc_cleanup_pending_mbox(vport);
6319 lpfc_mbx_unreg_vpi(vport); 6321 lpfc_mbx_unreg_vpi(vport);
6320 spin_lock_irq(shost->host_lock); 6322 spin_lock_irq(shost->host_lock);
6321 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 6323 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index d2b55f05aa0..1f87b4fb8b5 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -475,6 +475,10 @@ lpfc_work_list_done(struct lpfc_hba *phba)
475 lpfc_send_fastpath_evt(phba, evtp); 475 lpfc_send_fastpath_evt(phba, evtp);
476 free_evt = 0; 476 free_evt = 0;
477 break; 477 break;
478 case LPFC_EVT_RESET_HBA:
479 if (!(phba->pport->load_flag & FC_UNLOADING))
480 lpfc_reset_hba(phba);
481 break;
478 } 482 }
479 if (free_evt) 483 if (free_evt)
480 kfree(evtp); 484 kfree(evtp);
@@ -2737,11 +2741,18 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
2737 switch (mb->mbxStatus) { 2741 switch (mb->mbxStatus) {
2738 case 0x0011: 2742 case 0x0011:
2739 case 0x0020: 2743 case 0x0020:
2740 case 0x9700:
2741 lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, 2744 lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
2742 "0911 cmpl_unreg_vpi, mb status = 0x%x\n", 2745 "0911 cmpl_unreg_vpi, mb status = 0x%x\n",
2743 mb->mbxStatus); 2746 mb->mbxStatus);
2744 break; 2747 break;
2748 /* If VPI is busy, reset the HBA */
2749 case 0x9700:
2750 lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
2751 "2798 Unreg_vpi failed vpi 0x%x, mb status = 0x%x\n",
2752 vport->vpi, mb->mbxStatus);
2753 if (!(phba->pport->load_flag & FC_UNLOADING))
2754 lpfc_workq_post_event(phba, NULL, NULL,
2755 LPFC_EVT_RESET_HBA);
2745 } 2756 }
2746 spin_lock_irq(shost->host_lock); 2757 spin_lock_irq(shost->host_lock);
2747 vport->vpi_state &= ~LPFC_VPI_REGISTERED; 2758 vport->vpi_state &= ~LPFC_VPI_REGISTERED;
@@ -3233,7 +3244,6 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
3233 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 3244 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3234 3245
3235 if (new_state == NLP_STE_UNMAPPED_NODE) { 3246 if (new_state == NLP_STE_UNMAPPED_NODE) {
3236 ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
3237 ndlp->nlp_flag &= ~NLP_NODEV_REMOVE; 3247 ndlp->nlp_flag &= ~NLP_NODEV_REMOVE;
3238 ndlp->nlp_type |= NLP_FC_NODE; 3248 ndlp->nlp_type |= NLP_FC_NODE;
3239 } 3249 }
@@ -4991,6 +5001,7 @@ lpfc_unregister_fcf_prep(struct lpfc_hba *phba)
4991 ndlp = lpfc_findnode_did(vports[i], Fabric_DID); 5001 ndlp = lpfc_findnode_did(vports[i], Fabric_DID);
4992 if (ndlp) 5002 if (ndlp)
4993 lpfc_cancel_retry_delay_tmo(vports[i], ndlp); 5003 lpfc_cancel_retry_delay_tmo(vports[i], ndlp);
5004 lpfc_cleanup_pending_mbox(vports[i]);
4994 lpfc_mbx_unreg_vpi(vports[i]); 5005 lpfc_mbx_unreg_vpi(vports[i]);
4995 shost = lpfc_shost_from_vport(vports[i]); 5006 shost = lpfc_shost_from_vport(vports[i]);
4996 spin_lock_irq(shost->host_lock); 5007 spin_lock_irq(shost->host_lock);
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 03681013d80..cd9697edf86 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -3227,12 +3227,26 @@ lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport)
3227 3227
3228 if (!vport) 3228 if (!vport)
3229 return NULL; 3229 return NULL;
3230 ndlp = lpfc_findnode_did(vport, Fabric_DID);
3231 if (!ndlp)
3232 return NULL;
3233 phba = vport->phba; 3230 phba = vport->phba;
3234 if (!phba) 3231 if (!phba)
3235 return NULL; 3232 return NULL;
3233 ndlp = lpfc_findnode_did(vport, Fabric_DID);
3234 if (!ndlp) {
3235 /* Cannot find existing Fabric ndlp, so allocate a new one */
3236 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
3237 if (!ndlp)
3238 return 0;
3239 lpfc_nlp_init(vport, ndlp, Fabric_DID);
3240 /* Set the node type */
3241 ndlp->nlp_type |= NLP_FABRIC;
3242 /* Put ndlp onto node list */
3243 lpfc_enqueue_node(vport, ndlp);
3244 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
3245 /* re-setup ndlp without removing from node list */
3246 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
3247 if (!ndlp)
3248 return 0;
3249 }
3236 if (phba->pport->port_state <= LPFC_FLOGI) 3250 if (phba->pport->port_state <= LPFC_FLOGI)
3237 return NULL; 3251 return NULL;
3238 /* If virtual link is not yet instantiated ignore CVL */ 3252 /* If virtual link is not yet instantiated ignore CVL */
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index e1086da6906..b90820a699f 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -637,11 +637,55 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
637 lpfc_unreg_rpi(vport, ndlp); 637 lpfc_unreg_rpi(vport, ndlp);
638 return 0; 638 return 0;
639} 639}
640/**
641 * lpfc_release_rpi - Release a RPI by issueing unreg_login mailbox cmd.
642 * @phba : Pointer to lpfc_hba structure.
643 * @vport: Pointer to lpfc_vport structure.
644 * @rpi : rpi to be release.
645 *
646 * This function will send a unreg_login mailbox command to the firmware
647 * to release a rpi.
648 **/
649void
650lpfc_release_rpi(struct lpfc_hba *phba,
651 struct lpfc_vport *vport,
652 uint16_t rpi)
653{
654 LPFC_MBOXQ_t *pmb;
655 int rc;
656
657 pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
658 GFP_KERNEL);
659 if (!pmb)
660 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
661 "2796 mailbox memory allocation failed \n");
662 else {
663 lpfc_unreg_login(phba, vport->vpi, rpi, pmb);
664 pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
665 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
666 if (rc == MBX_NOT_FINISHED)
667 mempool_free(pmb, phba->mbox_mem_pool);
668 }
669}
640 670
641static uint32_t 671static uint32_t
642lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 672lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
643 void *arg, uint32_t evt) 673 void *arg, uint32_t evt)
644{ 674{
675 struct lpfc_hba *phba;
676 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
677 MAILBOX_t *mb;
678 uint16_t rpi;
679
680 phba = vport->phba;
681 /* Release the RPI if reglogin completing */
682 if (!(phba->pport->load_flag & FC_UNLOADING) &&
683 (evt == NLP_EVT_CMPL_REG_LOGIN) &&
684 (!pmb->u.mb.mbxStatus)) {
685 mb = &pmb->u.mb;
686 rpi = pmb->u.mb.un.varWords[0];
687 lpfc_release_rpi(phba, vport, rpi);
688 }
645 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, 689 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
646 "0271 Illegal State Transition: node x%x " 690 "0271 Illegal State Transition: node x%x "
647 "event x%x, state x%x Data: x%x x%x\n", 691 "event x%x, state x%x Data: x%x x%x\n",
@@ -977,6 +1021,18 @@ static uint32_t
977lpfc_cmpl_reglogin_plogi_issue(struct lpfc_vport *vport, 1021lpfc_cmpl_reglogin_plogi_issue(struct lpfc_vport *vport,
978 struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) 1022 struct lpfc_nodelist *ndlp, void *arg, uint32_t evt)
979{ 1023{
1024 struct lpfc_hba *phba;
1025 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
1026 MAILBOX_t *mb = &pmb->u.mb;
1027 uint16_t rpi;
1028
1029 phba = vport->phba;
1030 /* Release the RPI */
1031 if (!(phba->pport->load_flag & FC_UNLOADING) &&
1032 !mb->mbxStatus) {
1033 rpi = pmb->u.mb.un.varWords[0];
1034 lpfc_release_rpi(phba, vport, rpi);
1035 }
980 return ndlp->nlp_state; 1036 return ndlp->nlp_state;
981} 1037}
982 1038
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 1ab7937097a..7a61455140b 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -12661,6 +12661,7 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
12661 struct lpfc_hba *phba = vport->phba; 12661 struct lpfc_hba *phba = vport->phba;
12662 LPFC_MBOXQ_t *mb, *nextmb; 12662 LPFC_MBOXQ_t *mb, *nextmb;
12663 struct lpfc_dmabuf *mp; 12663 struct lpfc_dmabuf *mp;
12664 struct lpfc_nodelist *ndlp;
12664 12665
12665 spin_lock_irq(&phba->hbalock); 12666 spin_lock_irq(&phba->hbalock);
12666 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { 12667 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
@@ -12677,6 +12678,11 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
12677 __lpfc_mbuf_free(phba, mp->virt, mp->phys); 12678 __lpfc_mbuf_free(phba, mp->virt, mp->phys);
12678 kfree(mp); 12679 kfree(mp);
12679 } 12680 }
12681 ndlp = (struct lpfc_nodelist *) mb->context2;
12682 if (ndlp) {
12683 lpfc_nlp_put(ndlp);
12684 mb->context2 = NULL;
12685 }
12680 } 12686 }
12681 list_del(&mb->list); 12687 list_del(&mb->list);
12682 mempool_free(mb, phba->mbox_mem_pool); 12688 mempool_free(mb, phba->mbox_mem_pool);
@@ -12686,6 +12692,15 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
12686 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) || 12692 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) ||
12687 (mb->u.mb.mbxCommand == MBX_REG_VPI)) 12693 (mb->u.mb.mbxCommand == MBX_REG_VPI))
12688 mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; 12694 mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
12695 if (mb->u.mb.mbxCommand == MBX_REG_LOGIN64) {
12696 ndlp = (struct lpfc_nodelist *) mb->context2;
12697 if (ndlp) {
12698 lpfc_nlp_put(ndlp);
12699 mb->context2 = NULL;
12700 }
12701 /* Unregister the RPI when mailbox complete */
12702 mb->mbox_flag |= LPFC_MBX_IMED_UNREG;
12703 }
12689 } 12704 }
12690 spin_unlock_irq(&phba->hbalock); 12705 spin_unlock_irq(&phba->hbalock);
12691} 12706}