aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2013-04-17 20:14:38 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-05-02 15:37:45 -0400
commit16a3a20842f3df93f4ccb82b8f374be16280a337 (patch)
tree6291b5e85a7cac6b0d888dca3ed2a49ef5984de2
parent96b04db9f2c16e77c31ef0e17e143da1e0cbfd78 (diff)
[SCSI] lpfc 8.3.39: Fixed VPI allocation issues after firmware dump is performed
Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c14
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c12
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c25
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.h1
5 files changed, 51 insertions, 3 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 326e05a65a73..2ce2ebcc8f17 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -2796,7 +2796,19 @@ void
2796lpfc_issue_init_vpi(struct lpfc_vport *vport) 2796lpfc_issue_init_vpi(struct lpfc_vport *vport)
2797{ 2797{
2798 LPFC_MBOXQ_t *mboxq; 2798 LPFC_MBOXQ_t *mboxq;
2799 int rc; 2799 int rc, vpi;
2800
2801 if ((vport->port_type != LPFC_PHYSICAL_PORT) && (!vport->vpi)) {
2802 vpi = lpfc_alloc_vpi(vport->phba);
2803 if (!vpi) {
2804 lpfc_printf_vlog(vport, KERN_ERR,
2805 LOG_MBOX,
2806 "3303 Failed to obtain vport vpi\n");
2807 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
2808 return;
2809 }
2810 vport->vpi = vpi;
2811 }
2800 2812
2801 mboxq = mempool_alloc(vport->phba->mbox_mem_pool, GFP_KERNEL); 2813 mboxq = mempool_alloc(vport->phba->mbox_mem_pool, GFP_KERNEL);
2802 if (!mboxq) { 2814 if (!mboxq) {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 5da297290262..8edef6c4d57a 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2633,6 +2633,7 @@ lpfc_online(struct lpfc_hba *phba)
2633 struct lpfc_vport *vport; 2633 struct lpfc_vport *vport;
2634 struct lpfc_vport **vports; 2634 struct lpfc_vport **vports;
2635 int i; 2635 int i;
2636 bool vpis_cleared = false;
2636 2637
2637 if (!phba) 2638 if (!phba)
2638 return 0; 2639 return 0;
@@ -2656,6 +2657,10 @@ lpfc_online(struct lpfc_hba *phba)
2656 lpfc_unblock_mgmt_io(phba); 2657 lpfc_unblock_mgmt_io(phba);
2657 return 1; 2658 return 1;
2658 } 2659 }
2660 spin_lock_irq(&phba->hbalock);
2661 if (!phba->sli4_hba.max_cfg_param.vpi_used)
2662 vpis_cleared = true;
2663 spin_unlock_irq(&phba->hbalock);
2659 } else { 2664 } else {
2660 if (lpfc_sli_hba_setup(phba)) { /* Initialize SLI2/SLI3 HBA */ 2665 if (lpfc_sli_hba_setup(phba)) { /* Initialize SLI2/SLI3 HBA */
2661 lpfc_unblock_mgmt_io(phba); 2666 lpfc_unblock_mgmt_io(phba);
@@ -2672,8 +2677,13 @@ lpfc_online(struct lpfc_hba *phba)
2672 vports[i]->fc_flag &= ~FC_OFFLINE_MODE; 2677 vports[i]->fc_flag &= ~FC_OFFLINE_MODE;
2673 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) 2678 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
2674 vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 2679 vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
2675 if (phba->sli_rev == LPFC_SLI_REV4) 2680 if (phba->sli_rev == LPFC_SLI_REV4) {
2676 vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; 2681 vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
2682 if ((vpis_cleared) &&
2683 (vports[i]->port_type !=
2684 LPFC_PHYSICAL_PORT))
2685 vports[i]->vpi = 0;
2686 }
2677 spin_unlock_irq(shost->host_lock); 2687 spin_unlock_irq(shost->host_lock);
2678 } 2688 }
2679 lpfc_destroy_vport_work_array(phba, vports); 2689 lpfc_destroy_vport_work_array(phba, vports);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 35dd17eb0f27..96fe1ef24689 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -5511,6 +5511,7 @@ lpfc_sli4_dealloc_extent(struct lpfc_hba *phba, uint16_t type)
5511 list_del_init(&rsrc_blk->list); 5511 list_del_init(&rsrc_blk->list);
5512 kfree(rsrc_blk); 5512 kfree(rsrc_blk);
5513 } 5513 }
5514 phba->sli4_hba.max_cfg_param.vpi_used = 0;
5514 break; 5515 break;
5515 case LPFC_RSC_TYPE_FCOE_XRI: 5516 case LPFC_RSC_TYPE_FCOE_XRI:
5516 kfree(phba->sli4_hba.xri_bmask); 5517 kfree(phba->sli4_hba.xri_bmask);
@@ -5811,6 +5812,7 @@ lpfc_sli4_dealloc_resource_identifiers(struct lpfc_hba *phba)
5811 lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_VFI); 5812 lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_VFI);
5812 } else { 5813 } else {
5813 kfree(phba->vpi_bmask); 5814 kfree(phba->vpi_bmask);
5815 phba->sli4_hba.max_cfg_param.vpi_used = 0;
5814 kfree(phba->vpi_ids); 5816 kfree(phba->vpi_ids);
5815 bf_set(lpfc_vpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); 5817 bf_set(lpfc_vpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
5816 kfree(phba->sli4_hba.xri_bmask); 5818 kfree(phba->sli4_hba.xri_bmask);
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index 0fe188e66000..e28e431564b0 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -80,7 +80,7 @@ inline void lpfc_vport_set_state(struct lpfc_vport *vport,
80 } 80 }
81} 81}
82 82
83static int 83int
84lpfc_alloc_vpi(struct lpfc_hba *phba) 84lpfc_alloc_vpi(struct lpfc_hba *phba)
85{ 85{
86 unsigned long vpi; 86 unsigned long vpi;
@@ -568,6 +568,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
568 struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; 568 struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
569 struct lpfc_hba *phba = vport->phba; 569 struct lpfc_hba *phba = vport->phba;
570 long timeout; 570 long timeout;
571 bool ns_ndlp_referenced = false;
571 572
572 if (vport->port_type == LPFC_PHYSICAL_PORT) { 573 if (vport->port_type == LPFC_PHYSICAL_PORT) {
573 lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, 574 lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
@@ -628,6 +629,18 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
628 629
629 lpfc_debugfs_terminate(vport); 630 lpfc_debugfs_terminate(vport);
630 631
632 /*
633 * The call to fc_remove_host might release the NameServer ndlp. Since
634 * we might need to use the ndlp to send the DA_ID CT command,
635 * increment the reference for the NameServer ndlp to prevent it from
636 * being released.
637 */
638 ndlp = lpfc_findnode_did(vport, NameServer_DID);
639 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
640 lpfc_nlp_get(ndlp);
641 ns_ndlp_referenced = true;
642 }
643
631 /* Remove FC host and then SCSI host with the vport */ 644 /* Remove FC host and then SCSI host with the vport */
632 fc_remove_host(lpfc_shost_from_vport(vport)); 645 fc_remove_host(lpfc_shost_from_vport(vport));
633 scsi_remove_host(lpfc_shost_from_vport(vport)); 646 scsi_remove_host(lpfc_shost_from_vport(vport));
@@ -734,6 +747,16 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
734 lpfc_discovery_wait(vport); 747 lpfc_discovery_wait(vport);
735 748
736skip_logo: 749skip_logo:
750
751 /*
752 * If the NameServer ndlp has been incremented to allow the DA_ID CT
753 * command to be sent, decrement the ndlp now.
754 */
755 if (ns_ndlp_referenced) {
756 ndlp = lpfc_findnode_did(vport, NameServer_DID);
757 lpfc_nlp_put(ndlp);
758 }
759
737 lpfc_cleanup(vport); 760 lpfc_cleanup(vport);
738 lpfc_sli_host_down(vport); 761 lpfc_sli_host_down(vport);
739 762
diff --git a/drivers/scsi/lpfc/lpfc_vport.h b/drivers/scsi/lpfc/lpfc_vport.h
index 90828340acea..6b2c94eb8134 100644
--- a/drivers/scsi/lpfc/lpfc_vport.h
+++ b/drivers/scsi/lpfc/lpfc_vport.h
@@ -90,6 +90,7 @@ int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *);
90int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint); 90int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint);
91struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *); 91struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *);
92void lpfc_destroy_vport_work_array(struct lpfc_hba *, struct lpfc_vport **); 92void lpfc_destroy_vport_work_array(struct lpfc_hba *, struct lpfc_vport **);
93int lpfc_alloc_vpi(struct lpfc_hba *phba);
93 94
94/* 95/*
95 * queuecommand VPORT-specific return codes. Specified in the host byte code. 96 * queuecommand VPORT-specific return codes. Specified in the host byte code.