diff mbox series

[v9,06/13] lpfc: vmid: Add support for vmid in mailbox command, does vmid resource allocation and vmid cleanup

Message ID 1617750397-26466-7-git-send-email-muneendra.kumar@broadcom.com
State Superseded
Headers show
Series blkcg:Support to track FC storage blk io traffic | expand

Commit Message

Muneendra Kumar April 6, 2021, 11:06 p.m. UTC
From: Gaurav Srivastava <gaurav.srivastava@broadcom.com>

This patch does the following -
1.adds supporting datastructures for mailbox command which helps in
determining if the firmware supports appid or not.
2.This patch allocates the resource for vmid and checks if the firmware
supports the feature or not.
3.The patch cleans up the vmid resources and stops the timer.

Signed-off-by: Gaurav Srivastava <gaurav.srivastava@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>

---
v9:
Modified code for use of hashtable

v8:
Added new function declaration, return error code and
memory allocation API changes

v7:
No change

v6:
Added Forward declarations and functions to static

v5:
Merged patches 8 and 11 of v4 to this patch
Changed Return code to non-numeric/Symbol

v4:
No change

v3:
No change

v2:
Ported the patch on top of 5.10/scsi-queue
---
 drivers/scsi/lpfc/lpfc_hw4.h  | 12 +++++++
 drivers/scsi/lpfc/lpfc_init.c | 64 +++++++++++++++++++++++++++++++++++
 drivers/scsi/lpfc/lpfc_mbox.c |  6 ++++
 drivers/scsi/lpfc/lpfc_scsi.c | 29 ++++++++++++++++
 drivers/scsi/lpfc/lpfc_sli.c  |  9 +++++
 5 files changed, 120 insertions(+)

Comments

Hannes Reinecke April 8, 2021, 8:32 a.m. UTC | #1
On 4/7/21 1:06 AM, Muneendra wrote:
> From: Gaurav Srivastava <gaurav.srivastava@broadcom.com>

> 

> This patch does the following -

> 1.adds supporting datastructures for mailbox command which helps in

> determining if the firmware supports appid or not.

> 2.This patch allocates the resource for vmid and checks if the firmware

> supports the feature or not.

> 3.The patch cleans up the vmid resources and stops the timer.

> 

> Signed-off-by: Gaurav Srivastava <gaurav.srivastava@broadcom.com>

> Signed-off-by: James Smart <jsmart2021@gmail.com>

> 

> ---

> v9:

> Modified code for use of hashtable

> 

> v8:

> Added new function declaration, return error code and

> memory allocation API changes

> 

> v7:

> No change

> 

> v6:

> Added Forward declarations and functions to static

> 

> v5:

> Merged patches 8 and 11 of v4 to this patch

> Changed Return code to non-numeric/Symbol

> 

> v4:

> No change

> 

> v3:

> No change

> 

> v2:

> Ported the patch on top of 5.10/scsi-queue

> ---

>   drivers/scsi/lpfc/lpfc_hw4.h  | 12 +++++++

>   drivers/scsi/lpfc/lpfc_init.c | 64 +++++++++++++++++++++++++++++++++++

>   drivers/scsi/lpfc/lpfc_mbox.c |  6 ++++

>   drivers/scsi/lpfc/lpfc_scsi.c | 29 ++++++++++++++++

>   drivers/scsi/lpfc/lpfc_sli.c  |  9 +++++

>   5 files changed, 120 insertions(+)

> 

> diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h

> index 541b9aef6bfe..5fdafc92fc2d 100644

> --- a/drivers/scsi/lpfc/lpfc_hw4.h

> +++ b/drivers/scsi/lpfc/lpfc_hw4.h

> @@ -272,6 +272,9 @@ struct lpfc_sli4_flags {

>   #define lpfc_vfi_rsrc_rdy_MASK		0x00000001

>   #define lpfc_vfi_rsrc_rdy_WORD		word0

>   #define LPFC_VFI_RSRC_RDY		1

> +#define lpfc_ftr_ashdr_SHIFT            4

> +#define lpfc_ftr_ashdr_MASK             0x00000001

> +#define lpfc_ftr_ashdr_WORD             word0

>   };

>   

>   struct sli4_bls_rsp {

> @@ -2943,6 +2946,9 @@ struct lpfc_mbx_request_features {

>   #define lpfc_mbx_rq_ftr_rq_mrqp_SHIFT		16

>   #define lpfc_mbx_rq_ftr_rq_mrqp_MASK		0x00000001

>   #define lpfc_mbx_rq_ftr_rq_mrqp_WORD		word2

> +#define lpfc_mbx_rq_ftr_rq_ashdr_SHIFT          17

> +#define lpfc_mbx_rq_ftr_rq_ashdr_MASK           0x00000001

> +#define lpfc_mbx_rq_ftr_rq_ashdr_WORD           word2

>   	uint32_t word3;

>   #define lpfc_mbx_rq_ftr_rsp_iaab_SHIFT		0

>   #define lpfc_mbx_rq_ftr_rsp_iaab_MASK		0x00000001

> @@ -2974,6 +2980,9 @@ struct lpfc_mbx_request_features {

>   #define lpfc_mbx_rq_ftr_rsp_mrqp_SHIFT		16

>   #define lpfc_mbx_rq_ftr_rsp_mrqp_MASK		0x00000001

>   #define lpfc_mbx_rq_ftr_rsp_mrqp_WORD		word3

> +#define lpfc_mbx_rq_ftr_rsp_ashdr_SHIFT         17

> +#define lpfc_mbx_rq_ftr_rsp_ashdr_MASK          0x00000001

> +#define lpfc_mbx_rq_ftr_rsp_ashdr_WORD          word3

>   };

>   

>   struct lpfc_mbx_supp_pages {

> @@ -4391,6 +4400,9 @@ struct wqe_common {

>   #define wqe_xchg_WORD         word10

>   #define LPFC_SCSI_XCHG	      0x0

>   #define LPFC_NVME_XCHG	      0x1

> +#define wqe_appid_SHIFT       5

> +#define wqe_appid_MASK        0x00000001

> +#define wqe_appid_WORD        word10

>   #define wqe_oas_SHIFT         6

>   #define wqe_oas_MASK          0x00000001

>   #define wqe_oas_WORD          word10

> diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c

> index 5ea43c527e08..a506ab453343 100644

> --- a/drivers/scsi/lpfc/lpfc_init.c

> +++ b/drivers/scsi/lpfc/lpfc_init.c

> @@ -98,6 +98,7 @@ static struct scsi_transport_template *lpfc_transport_template = NULL;

>   static struct scsi_transport_template *lpfc_vport_transport_template = NULL;

>   static DEFINE_IDR(lpfc_hba_index);

>   #define LPFC_NVMET_BUF_POST 254

> +static int lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport);

>   

>   /**

>    * lpfc_config_port_prep - Perform lpfc initialization prior to config port

> @@ -2888,6 +2889,10 @@ lpfc_cleanup(struct lpfc_vport *vport)

>   	if (phba->link_state > LPFC_LINK_DOWN)

>   		lpfc_port_link_failure(vport);

>   

> +	/* cleanup vmid resources */

> +	if (lpfc_is_vmid_enabled(phba))

> +		lpfc_vmid_vport_cleanup(vport);

> +

>   	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {

>   		if (vport->port_type != LPFC_PHYSICAL_PORT &&

>   		    ndlp->nlp_DID == Fabric_DID) {

> @@ -4318,6 +4323,57 @@ lpfc_get_wwpn(struct lpfc_hba *phba)

>   		return rol64(wwn, 32);

>   }

>   

> +/**

> + * lpfc_vmid_res_alloc - Allocates resources for VMID

> + * @phba: pointer to lpfc hba data structure.

> + * @vport: pointer to vport data structure

> + *

> + * This routine allocated the resources needed for the vmid.

> + *

> + * Return codes

> + *	0 on Succeess

> + *	Non-0 on Failure

> + */

> +static int

> +lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport)

> +{

> +	/* vmid feature is supported only on SLI4 */

> +	if (phba->sli_rev == LPFC_SLI_REV3) {

> +		phba->cfg_vmid_app_header = 0;

> +		phba->cfg_vmid_priority_tagging = 0;

> +	}

> +

> +	/* if enabled, then allocated the resources */

> +	if (lpfc_is_vmid_enabled(phba)) {

> +		vport->vmid =

> +		    kcalloc(phba->cfg_max_vmid, sizeof(struct lpfc_vmid),

> +			    GFP_KERNEL);

> +		if (!vport->vmid)

> +			return -ENOMEM;

> +

> +		rwlock_init(&vport->vmid_lock);

> +

> +		/* setting the VMID parameters for the vport */

> +		vport->vmid_priority_tagging = phba->cfg_vmid_priority_tagging;

> +		vport->vmid_inactivity_timeout =

> +		    phba->cfg_vmid_inactivity_timeout;

> +		vport->max_vmid = phba->cfg_max_vmid;

> +		vport->cur_vmid_cnt = 0;

> +

> +		vport->vmid_priority_range = bitmap_zalloc

> +			(LPFC_VMID_MAX_PRIORITY_RANGE, GFP_KERNEL);

> +

> +		if (!vport->vmid_priority_range) {

> +			kfree(vport->vmid);

> +			return -ENOMEM;

> +		}

> +

> +		/* Initialize the hashtable */

> +		hash_init(vport->hash_table);

> +	}

> +	return 0;

> +}

> +

>   /**

>    * lpfc_create_port - Create an FC port

>    * @phba: pointer to lpfc hba data structure.

> @@ -4470,6 +4526,12 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)

>   			vport->port_type, shost->sg_tablesize,

>   			phba->cfg_scsi_seg_cnt, phba->cfg_sg_seg_cnt);

>   

> +	/* allocate the resources for vmid */

> +	rc = lpfc_vmid_res_alloc(phba, vport);

> +

> +	if (rc)

> +		goto out;

> +

>   	/* Initialize all internally managed lists. */

>   	INIT_LIST_HEAD(&vport->fc_nodes);

>   	INIT_LIST_HEAD(&vport->rcv_buffer_list);

> @@ -4494,6 +4556,8 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)

>   	return vport;

>   

>   out_put_shost:

> +	kfree(vport->vmid);

> +	bitmap_free(vport->vmid_priority_range);

>   	scsi_host_put(shost);

>   out:

>   	return NULL;

> diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c

> index c03a7f12dd65..7a15986ed586 100644

> --- a/drivers/scsi/lpfc/lpfc_mbox.c

> +++ b/drivers/scsi/lpfc/lpfc_mbox.c

> @@ -2100,6 +2100,12 @@ lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq)

>   		bf_set(lpfc_mbx_rq_ftr_rq_iaab, &mboxq->u.mqe.un.req_ftrs, 0);

>   		bf_set(lpfc_mbx_rq_ftr_rq_iaar, &mboxq->u.mqe.un.req_ftrs, 0);

>   	}

> +

> +	/* Enable Application Services Header for apphedr VMID */

> +	if (phba->cfg_vmid_app_header) {

> +		bf_set(lpfc_mbx_rq_ftr_rq_ashdr, &mboxq->u.mqe.un.req_ftrs, 1);

> +		bf_set(lpfc_ftr_ashdr, &phba->sli4_hba.sli4_flags, 1);

> +	}

>   	return;

>   }

>   

> diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c

> index 85f6a066de5a..0868cb38d5b0 100644

> --- a/drivers/scsi/lpfc/lpfc_scsi.c

> +++ b/drivers/scsi/lpfc/lpfc_scsi.c

> @@ -5384,6 +5384,35 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)

>   	return 0;

>   }

>   

> +/*

> + * lpfc_vmid_vport_cleanup - cleans up the resources associated with a vports

> + * @vport: The virtual port for which this call is being executed.

> + */

> +void lpfc_vmid_vport_cleanup(struct lpfc_vport *vport)

> +{

> +	u32 bucket;

> +	struct lpfc_vmid *cur;

> +

> +	/* delete the timer */

> +	if (vport->port_type == LPFC_PHYSICAL_PORT)

> +		del_timer_sync(&vport->phba->inactive_vmid_poll);

> +

> +	/* free the resources */

> +	kfree(vport->qfpa_res);

> +	kfree(vport->vmid_priority.vmid_range);

> +	kfree(vport->vmid);

> +

> +	/* for all elements in the hash table */

> +	if (!hash_empty(vport->hash_table))

> +		hash_for_each(vport->hash_table, bucket, cur, hnode)

> +			hash_del(&cur->hnode);

> +

> +	/* reset variables */

> +	vport->qfpa_res = NULL;

> +	vport->vmid_priority.vmid_range = NULL;

> +	vport->vmid = NULL;

> +	vport->cur_vmid_cnt = 0;

> +}

>   

>   /**

>    * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point

> diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c

> index f6e1e36eabdc..3f212555f3ac 100644

> --- a/drivers/scsi/lpfc/lpfc_sli.c

> +++ b/drivers/scsi/lpfc/lpfc_sli.c

> @@ -7698,6 +7698,15 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)

>   		goto out_free_mbox;

>   	}

>   

> +	/* Disable vmid if app header is not supported */

> +	if (phba->cfg_vmid_app_header && !(bf_get(lpfc_mbx_rq_ftr_rsp_ashdr,

> +						  &mqe->un.req_ftrs))) {

> +		bf_set(lpfc_ftr_ashdr, &phba->sli4_hba.sli4_flags, 0);

> +		phba->cfg_vmid_app_header = 0;

> +		lpfc_printf_log(phba, KERN_DEBUG, LOG_SLI,

> +				"1242 vmid feature not supported\n");

> +	}

> +

>   	/*

>   	 * The port must support FCP initiator mode as this is the

>   	 * only mode running in the host.

> 

I would have thought that the forward declaration for 
lpfc_vport_cleanup() should be present in this patch (and not the 
previous one).
But that's largely cosmetical, so:

Reviewed-by: Hannes Reinecke <hare@suse.de>


Cheers,

Hannes
-- 
Dr. Hannes Reinecke                Kernel Storage Architect
hare@suse.de                              +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer
diff mbox series

Patch

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 541b9aef6bfe..5fdafc92fc2d 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -272,6 +272,9 @@  struct lpfc_sli4_flags {
 #define lpfc_vfi_rsrc_rdy_MASK		0x00000001
 #define lpfc_vfi_rsrc_rdy_WORD		word0
 #define LPFC_VFI_RSRC_RDY		1
+#define lpfc_ftr_ashdr_SHIFT            4
+#define lpfc_ftr_ashdr_MASK             0x00000001
+#define lpfc_ftr_ashdr_WORD             word0
 };
 
 struct sli4_bls_rsp {
@@ -2943,6 +2946,9 @@  struct lpfc_mbx_request_features {
 #define lpfc_mbx_rq_ftr_rq_mrqp_SHIFT		16
 #define lpfc_mbx_rq_ftr_rq_mrqp_MASK		0x00000001
 #define lpfc_mbx_rq_ftr_rq_mrqp_WORD		word2
+#define lpfc_mbx_rq_ftr_rq_ashdr_SHIFT          17
+#define lpfc_mbx_rq_ftr_rq_ashdr_MASK           0x00000001
+#define lpfc_mbx_rq_ftr_rq_ashdr_WORD           word2
 	uint32_t word3;
 #define lpfc_mbx_rq_ftr_rsp_iaab_SHIFT		0
 #define lpfc_mbx_rq_ftr_rsp_iaab_MASK		0x00000001
@@ -2974,6 +2980,9 @@  struct lpfc_mbx_request_features {
 #define lpfc_mbx_rq_ftr_rsp_mrqp_SHIFT		16
 #define lpfc_mbx_rq_ftr_rsp_mrqp_MASK		0x00000001
 #define lpfc_mbx_rq_ftr_rsp_mrqp_WORD		word3
+#define lpfc_mbx_rq_ftr_rsp_ashdr_SHIFT         17
+#define lpfc_mbx_rq_ftr_rsp_ashdr_MASK          0x00000001
+#define lpfc_mbx_rq_ftr_rsp_ashdr_WORD          word3
 };
 
 struct lpfc_mbx_supp_pages {
@@ -4391,6 +4400,9 @@  struct wqe_common {
 #define wqe_xchg_WORD         word10
 #define LPFC_SCSI_XCHG	      0x0
 #define LPFC_NVME_XCHG	      0x1
+#define wqe_appid_SHIFT       5
+#define wqe_appid_MASK        0x00000001
+#define wqe_appid_WORD        word10
 #define wqe_oas_SHIFT         6
 #define wqe_oas_MASK          0x00000001
 #define wqe_oas_WORD          word10
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 5ea43c527e08..a506ab453343 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -98,6 +98,7 @@  static struct scsi_transport_template *lpfc_transport_template = NULL;
 static struct scsi_transport_template *lpfc_vport_transport_template = NULL;
 static DEFINE_IDR(lpfc_hba_index);
 #define LPFC_NVMET_BUF_POST 254
+static int lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport);
 
 /**
  * lpfc_config_port_prep - Perform lpfc initialization prior to config port
@@ -2888,6 +2889,10 @@  lpfc_cleanup(struct lpfc_vport *vport)
 	if (phba->link_state > LPFC_LINK_DOWN)
 		lpfc_port_link_failure(vport);
 
+	/* cleanup vmid resources */
+	if (lpfc_is_vmid_enabled(phba))
+		lpfc_vmid_vport_cleanup(vport);
+
 	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
 		if (vport->port_type != LPFC_PHYSICAL_PORT &&
 		    ndlp->nlp_DID == Fabric_DID) {
@@ -4318,6 +4323,57 @@  lpfc_get_wwpn(struct lpfc_hba *phba)
 		return rol64(wwn, 32);
 }
 
+/**
+ * lpfc_vmid_res_alloc - Allocates resources for VMID
+ * @phba: pointer to lpfc hba data structure.
+ * @vport: pointer to vport data structure
+ *
+ * This routine allocated the resources needed for the vmid.
+ *
+ * Return codes
+ *	0 on Succeess
+ *	Non-0 on Failure
+ */
+static int
+lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport)
+{
+	/* vmid feature is supported only on SLI4 */
+	if (phba->sli_rev == LPFC_SLI_REV3) {
+		phba->cfg_vmid_app_header = 0;
+		phba->cfg_vmid_priority_tagging = 0;
+	}
+
+	/* if enabled, then allocated the resources */
+	if (lpfc_is_vmid_enabled(phba)) {
+		vport->vmid =
+		    kcalloc(phba->cfg_max_vmid, sizeof(struct lpfc_vmid),
+			    GFP_KERNEL);
+		if (!vport->vmid)
+			return -ENOMEM;
+
+		rwlock_init(&vport->vmid_lock);
+
+		/* setting the VMID parameters for the vport */
+		vport->vmid_priority_tagging = phba->cfg_vmid_priority_tagging;
+		vport->vmid_inactivity_timeout =
+		    phba->cfg_vmid_inactivity_timeout;
+		vport->max_vmid = phba->cfg_max_vmid;
+		vport->cur_vmid_cnt = 0;
+
+		vport->vmid_priority_range = bitmap_zalloc
+			(LPFC_VMID_MAX_PRIORITY_RANGE, GFP_KERNEL);
+
+		if (!vport->vmid_priority_range) {
+			kfree(vport->vmid);
+			return -ENOMEM;
+		}
+
+		/* Initialize the hashtable */
+		hash_init(vport->hash_table);
+	}
+	return 0;
+}
+
 /**
  * lpfc_create_port - Create an FC port
  * @phba: pointer to lpfc hba data structure.
@@ -4470,6 +4526,12 @@  lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
 			vport->port_type, shost->sg_tablesize,
 			phba->cfg_scsi_seg_cnt, phba->cfg_sg_seg_cnt);
 
+	/* allocate the resources for vmid */
+	rc = lpfc_vmid_res_alloc(phba, vport);
+
+	if (rc)
+		goto out;
+
 	/* Initialize all internally managed lists. */
 	INIT_LIST_HEAD(&vport->fc_nodes);
 	INIT_LIST_HEAD(&vport->rcv_buffer_list);
@@ -4494,6 +4556,8 @@  lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
 	return vport;
 
 out_put_shost:
+	kfree(vport->vmid);
+	bitmap_free(vport->vmid_priority_range);
 	scsi_host_put(shost);
 out:
 	return NULL;
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index c03a7f12dd65..7a15986ed586 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -2100,6 +2100,12 @@  lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq)
 		bf_set(lpfc_mbx_rq_ftr_rq_iaab, &mboxq->u.mqe.un.req_ftrs, 0);
 		bf_set(lpfc_mbx_rq_ftr_rq_iaar, &mboxq->u.mqe.un.req_ftrs, 0);
 	}
+
+	/* Enable Application Services Header for apphedr VMID */
+	if (phba->cfg_vmid_app_header) {
+		bf_set(lpfc_mbx_rq_ftr_rq_ashdr, &mboxq->u.mqe.un.req_ftrs, 1);
+		bf_set(lpfc_ftr_ashdr, &phba->sli4_hba.sli4_flags, 1);
+	}
 	return;
 }
 
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 85f6a066de5a..0868cb38d5b0 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -5384,6 +5384,35 @@  lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
 	return 0;
 }
 
+/*
+ * lpfc_vmid_vport_cleanup - cleans up the resources associated with a vports
+ * @vport: The virtual port for which this call is being executed.
+ */
+void lpfc_vmid_vport_cleanup(struct lpfc_vport *vport)
+{
+	u32 bucket;
+	struct lpfc_vmid *cur;
+
+	/* delete the timer */
+	if (vport->port_type == LPFC_PHYSICAL_PORT)
+		del_timer_sync(&vport->phba->inactive_vmid_poll);
+
+	/* free the resources */
+	kfree(vport->qfpa_res);
+	kfree(vport->vmid_priority.vmid_range);
+	kfree(vport->vmid);
+
+	/* for all elements in the hash table */
+	if (!hash_empty(vport->hash_table))
+		hash_for_each(vport->hash_table, bucket, cur, hnode)
+			hash_del(&cur->hnode);
+
+	/* reset variables */
+	vport->qfpa_res = NULL;
+	vport->vmid_priority.vmid_range = NULL;
+	vport->vmid = NULL;
+	vport->cur_vmid_cnt = 0;
+}
 
 /**
  * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index f6e1e36eabdc..3f212555f3ac 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -7698,6 +7698,15 @@  lpfc_sli4_hba_setup(struct lpfc_hba *phba)
 		goto out_free_mbox;
 	}
 
+	/* Disable vmid if app header is not supported */
+	if (phba->cfg_vmid_app_header && !(bf_get(lpfc_mbx_rq_ftr_rsp_ashdr,
+						  &mqe->un.req_ftrs))) {
+		bf_set(lpfc_ftr_ashdr, &phba->sli4_hba.sli4_flags, 0);
+		phba->cfg_vmid_app_header = 0;
+		lpfc_printf_log(phba, KERN_DEBUG, LOG_SLI,
+				"1242 vmid feature not supported\n");
+	}
+
 	/*
 	 * The port must support FCP initiator mode as this is the
 	 * only mode running in the host.