Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 2163

kernel-2.6.18-128.1.10.el5.src.rpm

From: Tom Coughlan <coughlan@redhat.com>
Date: Wed, 29 Oct 2008 21:50:28 -0400
Subject: [scsi] lpfc: Emulex RHEL-5.3 bugfixes
Message-id: 1225331430.32099.20.camel@p670.boston.redhat.com
O-Subject: Re: [RHEL 5.3 PATCH] Bug 461795 - Emulex lpfc bugfixes (updates driver version to 8.2.0.33)
Bugzilla: 461795
RH-Acked-by: Tomas Henzl <thenzl@redhat.com>

This is a re-post of the original patch in this thread. There are three
changes.

First, there is a fix for the memory leaks in netlink send code found by
Tomas in code review.

Second, remove unused struct fc_nl_sc_message_old.

Third, there is a fix for a bug found by Emulex QA. This fixes false
overrun failure on CNA devices for commands that are less than the
command header size.

(Please refer to the BZ to see the incremental patches:
https://bugzilla.redhat.com/show_bug.cgi?id=461795#c17
https://bugzilla.redhat.com/show_bug.cgi?id=461795#c28 )

Built in Brew.
http://brewweb.devel.redhat.com/brew/taskinfo?taskID=1546073

This update fixes lpfc bugs that were found after beta 5.3 freeze. It
also switches to use NETLINK_SCSITRANSPORT, for consistency with
upstream.

Changelog:

* Back out fix for slow vports on certain switches
* Use the NETLINK_SCSITRANSPORT on kernels that support it
* Fix internal and external loopback failing on Hornet
* Resolved uninitialized node access
* Fix echotest failure when NPIV is enabled
* Added support for hps bit

The latter fix is needed to support new Stoakely IOV servers.  This is a new
Intel server that we must have RHEL5 support for.

Symptoms:
On platforms with virtualized PCI address space CONFIG_PORT mailbox command and
CONFIG_RING mailbox commands fail causing the the driver attachment to fail,
resulting in no FC connectivity.

Cause:
The HBA uses a comparison of the host group pointer address with BAR register
values to determine if the host group pointers are in SLIM memory or not.  This
comparison will not work on systems with virtualized PCI address space.

Fix:
Implemented support for HPS bit in the CONFIG_PORT mailbox command.  This bit
is always set in the Linux driver and will tell the HBA that the host group
pointers are in host memory and prevent the comparison.

Boot tested on x86_64.

Tom

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 3b54fa9..49c0693 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -3765,7 +3765,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
 	phba->cfg_soft_wwpn = 0L;
 	lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
 	/* Also reinitialize the host templates with new values. */
-	lpfc_template_no_npiv.sg_tablesize = phba->cfg_sg_seg_cnt;
 	lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt;
 	lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt;
 	/*
diff --git a/drivers/scsi/lpfc/lpfc_auth_access.c b/drivers/scsi/lpfc/lpfc_auth_access.c
index d41e611..9e95f66 100644
--- a/drivers/scsi/lpfc/lpfc_auth_access.c
+++ b/drivers/scsi/lpfc/lpfc_auth_access.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2006-2007 Emulex.  All rights reserved.           *
+ * Copyright (C) 2006-2008 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -49,9 +49,7 @@
 #include "lpfc_auth_access.h"
 
 /* fc security */
-char security_work_q_name[KOBJ_NAME_LEN];
-struct workqueue_struct *security_work_q = NULL;
-struct sock *fc_nl_sock;
+struct workqueue_struct *security_work_q;
 struct list_head fc_security_user_list;
 int fc_service_state = FC_SC_SERVICESTATE_UNKNOWN;
 static int fc_service_pid;
@@ -192,13 +190,9 @@ lpfc_fc_sc_request(struct lpfc_vport *vport,
 {
 	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 	struct fc_security_request *fc_sc_req;
-	struct sk_buff *skb;
-	struct nlmsghdr	*nlh;
 	struct fc_nl_sc_message *fc_nl_sc_msg;
-	const char *fn;
 	unsigned long flags;
 	u32 len;
-	int err = 0;
 	u32 seq = ++vport->sc_tran_id;
 
 	if (fc_service_state != FC_SC_SERVICESTATE_ONLINE)
@@ -208,7 +202,6 @@ lpfc_fc_sc_request(struct lpfc_vport *vport,
 		return -EINVAL;
 
 	fc_sc_req = kzalloc(sizeof(struct fc_security_request), GFP_KERNEL);
-
 	if (!fc_sc_req)
 		return -ENOMEM;
 
@@ -216,64 +209,29 @@ lpfc_fc_sc_request(struct lpfc_vport *vport,
 	fc_sc_req->data = auth_rsp;
 	fc_sc_req->data_len = auth_rsp_len;
 	fc_sc_req->vport = vport;
+	fc_sc_req->tran_id = seq;
 
-	len = NLMSG_SPACE(sizeof(struct fc_nl_sc_message) + auth_req_len);
-
-	skb = alloc_skb(len, GFP_KERNEL);
-	if (!skb) {
-		err = -ENOBUFS;
-		fn = "alloc_skb";
-		goto send_fail;
-	}
-
-	nlh = nlmsg_put(skb, fc_service_pid, seq, FC_TRANSPORT_MSG,
-			len - sizeof(*nlh), 0);
-	if (!nlh) {
-		err = -ENOBUFS;
-		fn = "nlmsg_put";
-		goto send_fail;
+	len = sizeof(struct fc_nl_sc_message) + auth_req_len;
+	fc_nl_sc_msg = kzalloc(len, GFP_KERNEL);
+	if (!fc_nl_sc_msg) {
+		kfree(fc_sc_req);
+		return -ENOMEM;
 	}
-
-	fc_nl_sc_msg = NLMSG_DATA(nlh);
-	fc_nl_sc_msg->snlh.version = SCSI_NL_VERSION;
-	fc_nl_sc_msg->snlh.transport = SCSI_NL_TRANSPORT_FC;
-	fc_nl_sc_msg->snlh.magic = SCSI_NL_MAGIC;
-	fc_nl_sc_msg->snlh.msgtype = msg_type;
-	fc_nl_sc_msg->snlh.msglen = len;
+	fc_nl_sc_msg->msgtype = msg_type;
 	fc_nl_sc_msg->data_len = auth_req_len;
-	if (auth_req_len)
-		memcpy(fc_nl_sc_msg->data, auth_req, auth_req_len);
-
-	fc_nl_sc_msg->host_no = shost->host_no;
+	memcpy(fc_nl_sc_msg->data, auth_req, auth_req_len);
 	fc_nl_sc_msg->tran_id = seq;
-	fc_sc_req->tran_id = seq;
 
 	spin_lock_irqsave(shost->host_lock, flags);
 	list_add_tail(&fc_sc_req->rlist, &vport->sc_response_wait_queue);
 	spin_unlock_irqrestore(shost->host_lock, flags);
-
-	err = nlmsg_unicast(fc_nl_sock, skb, fc_service_pid);
-	if (err < 0) {
-		fn = "nlmsg_unicast";
-		spin_lock_irqsave(shost->host_lock, flags);
-		list_del(&fc_sc_req->rlist);
-		spin_unlock_irqrestore(shost->host_lock, flags);
-		goto send_fail;
-	}
+	scsi_nl_send_vendor_msg(fc_service_pid, shost->host_no,
+				(SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX),
+				(char *) fc_nl_sc_msg, len);
+	kfree(fc_nl_sc_msg);
 	lpfc_fc_sc_add_timer(fc_sc_req, FC_SC_REQ_TIMEOUT,
 			     lpfc_fc_sc_req_times_out);
-
 	return 0;
-
-send_fail:
-
-	kfree(fc_sc_req);
-
-	lpfc_printf_vlog(vport, KERN_WARNING, LOG_SECURITY,
-			 "1020 Dropped Message type %d to PID %d : %s : err "
-			 "%d\n", msg_type, fc_service_pid, fn, err);
-	return err;
-
 }
 
 /**
@@ -507,28 +465,16 @@ lpfc_fc_sc_process_msg(struct work_struct *work)
  **/
 
 int
-lpfc_fc_sc_schedule_msg(struct fc_nl_sc_message *fc_nl_sc_msg, int rcvlen)
+lpfc_fc_sc_schedule_msg(struct Scsi_Host *shost,
+			struct fc_nl_sc_message *fc_nl_sc_msg, int rcvlen)
 {
 	struct fc_security_request *fc_sc_req;
 	u32 req_type;
-	struct lpfc_vport *vport = 0;
 	int err = 0;
 	struct fc_sc_msg_work_q_wrapper *wqw;
 	unsigned long flags;
-	struct Scsi_Host *shost;
-
-	spin_lock_irqsave(&fc_security_user_lock, flags);
-
-	vport = lpfc_fc_find_vport(fc_nl_sc_msg->host_no);
-
-	spin_unlock_irqrestore(&fc_security_user_lock, flags);
-	if (!vport) {
-		printk(KERN_WARNING
-			"%s: Host does not exist for msg type %x.\n",
-			__func__, fc_nl_sc_msg->snlh.msgtype);
-		return -EBADR;
-	}
-	shost = lpfc_shost_from_vport(vport);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	int msg_type = fc_nl_sc_msg->msgtype;
 
 	if (vport->port_state == FC_PORTSTATE_DELETED) {
 		printk(KERN_WARNING
@@ -541,7 +487,7 @@ lpfc_fc_sc_schedule_msg(struct fc_nl_sc_message *fc_nl_sc_msg, int rcvlen)
 	if (!wqw)
 		return -ENOMEM;
 
-	switch (fc_nl_sc_msg->snlh.msgtype) {
+	switch (msg_type) {
 	case FC_NL_SC_GET_CONFIG_RSP:
 		req_type = FC_NL_SC_GET_CONFIG_REQ;
 		break;
@@ -585,8 +531,7 @@ lpfc_fc_sc_schedule_msg(struct fc_nl_sc_message *fc_nl_sc_msg, int rcvlen)
 	wqw->status = 0;
 	wqw->fc_sc_req = fc_sc_req;
 	wqw->data_len = rcvlen;
-	wqw->msgtype = fc_nl_sc_msg->snlh.msgtype;
-
+	wqw->msgtype = msg_type;
 	if (!fc_sc_req->data ||
 		(fc_sc_req->data_len < fc_nl_sc_msg->data_len)) {
 		wqw->status = -ENOBUFS;
@@ -608,147 +553,48 @@ lpfc_fc_sc_schedule_msg(struct fc_nl_sc_message *fc_nl_sc_msg, int rcvlen)
 	return err;
 }
 
-static int
-lpfc_fc_handle_nl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int rcvlen)
+int
+lpfc_rcv_nl_msg(struct Scsi_Host *shost, void *payload,
+		uint32_t len, uint32_t pid)
 {
-	struct scsi_nl_hdr *snlh = NLMSG_DATA(nlh);
+	struct fc_nl_sc_message *msg = (struct fc_nl_sc_message *)payload;
 	int err = 0;
-	int pid;
-
-	pid = nlh->nlmsg_pid;
-
-	switch (snlh->msgtype) {
-
+	switch (msg->msgtype) {
 	case FC_NL_SC_REG:
-
-		fc_service_pid = nlh->nlmsg_pid;
+		fc_service_pid = pid;
 		fc_service_state = FC_SC_SERVICESTATE_ONLINE;
-		if (nlh->nlmsg_flags & NLM_F_ACK)
-			netlink_ack(skb, nlh, err);
-		skb_pull(skb, rcvlen);
 		lpfc_fc_sc_schedule_notify_all(FC_NL_SC_REG);
 		break;
-
 	case FC_NL_SC_DEREG:
-
-		fc_service_pid = nlh->nlmsg_pid;
+		fc_service_pid = pid;
 		fc_service_state = FC_SC_SERVICESTATE_OFFLINE;
-		if (nlh->nlmsg_flags & NLM_F_ACK)
-			netlink_ack(skb, nlh, err);
-		skb_pull(skb, rcvlen);
 		lpfc_fc_sc_schedule_notify_all(FC_NL_SC_DEREG);
 		break;
-
 	case FC_NL_SC_GET_CONFIG_RSP:
 	case FC_NL_SC_DHCHAP_MAKE_CHALLENGE_RSP:
 	case FC_NL_SC_DHCHAP_MAKE_RESPONSE_RSP:
 	case FC_NL_SC_DHCHAP_AUTHENTICATE_RSP:
-
-		err = lpfc_fc_sc_schedule_msg((struct fc_nl_sc_message *)snlh,
-				rcvlen);
-
-		if ((nlh->nlmsg_flags & NLM_F_ACK) || err)
-			netlink_ack(skb, nlh, err);
-
-		skb_pull(skb, rcvlen);
+		err = lpfc_fc_sc_schedule_msg(shost, msg, len);
 		break;
-
 	default:
 		printk(KERN_WARNING "%s: unknown msg type 0x%x len %d\n",
-		       __func__, snlh->msgtype, rcvlen);
-		netlink_ack(skb, nlh, -EBADR);
-		skb_pull(skb, rcvlen);
+		       __func__, msg->msgtype, len);
 		break;
 	}
-
 	return err;
 }
 
 void
-lpfc_fc_nl_rcv_msg(struct sk_buff *skb)
-{
-	struct nlmsghdr *nlh;
-	struct scsi_nl_hdr *snlh;
-	uint32_t rlen;
-	int err;
-
-	while (skb->len >= NLMSG_SPACE(0)) {
-		err = 0;
-
-		nlh = (struct nlmsghdr *) skb->data;
-
-		if ((nlh->nlmsg_len < (sizeof(*nlh) + sizeof(*snlh))) ||
-		    (skb->len < nlh->nlmsg_len)) {
-			printk(KERN_WARNING "%s: discarding partial skb\n",
-			       __func__);
-			break;
-		}
-
-		rlen = NLMSG_ALIGN(nlh->nlmsg_len);
-		if (rlen > skb->len) {
-			printk(KERN_WARNING "%s: rlen > skb->len\n",
-				 __func__);
-			rlen = skb->len;
-		}
-
-		if (nlh->nlmsg_type != FC_TRANSPORT_MSG) {
-			printk(KERN_WARNING "%s: Not FC_TRANSPORT_MSG\n",
-			       __func__);
-			err = -EBADMSG;
-			goto next_msg;
-		}
-
-		snlh = NLMSG_DATA(nlh);
-		if ((snlh->version != SCSI_NL_VERSION) ||
-		    (snlh->magic != SCSI_NL_MAGIC)) {
-			printk(KERN_WARNING "%s: Bad Version or Magic number\n",
-			       __func__);
-			err = -EPROTOTYPE;
-			goto next_msg;
-		}
-
-next_msg:
-		if (err) {
-			printk(KERN_WARNING "%s: err %d\n", __func__, err);
-			netlink_ack(skb, nlh, err);
-			skb_pull(skb, rlen);
-			continue;
-		}
-
-		lpfc_fc_handle_nl_rcv_msg(skb, nlh, rlen);
-	}
-}
-
-void
-lpfc_fc_nl_rcv(struct sock *sk, int len)
-{
-	struct sk_buff *skb;
-
-	while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
-		lpfc_fc_nl_rcv_msg(skb);
-		kfree_skb(skb);
-	}
-}
-
-int
-lpfc_fc_nl_rcv_nl_event(struct notifier_block *this,
+lpfc_rcv_nl_event(struct notifier_block *this,
 			unsigned long event,
 			void *ptr)
 {
 	struct netlink_notify *n = ptr;
-
 	if ((event == NETLINK_URELEASE) &&
-	    (n->protocol == NETLINK_FCTRANSPORT) && (n->pid)) {
+	    (n->protocol == NETLINK_SCSITRANSPORT) && (n->pid)) {
+		printk(KERN_WARNING "Warning - Security Service Offline\n");
 		fc_service_state = FC_SC_SERVICESTATE_OFFLINE;
 		lpfc_fc_sc_schedule_notify_all(FC_NL_SC_DEREG);
-		}
-
-	return NOTIFY_DONE;
+	}
 }
 
-struct notifier_block lpfc_fc_netlink_notifier = {
-	.notifier_call  = lpfc_fc_nl_rcv_nl_event,
-};
-
-
-
diff --git a/drivers/scsi/lpfc/lpfc_auth_access.h b/drivers/scsi/lpfc/lpfc_auth_access.h
index a57f3ba..5078671 100644
--- a/drivers/scsi/lpfc/lpfc_auth_access.h
+++ b/drivers/scsi/lpfc/lpfc_auth_access.h
@@ -206,7 +206,7 @@ int lpfc_fc_queue_security_work(struct lpfc_vport *,
 #define FC_NL_SC_DHCHAP_MAKE_RESPONSE_RSP	0x0008
 #define FC_NL_SC_DHCHAP_AUTHENTICATE_RSP	0x0009
 	/* kernel -> user */
-#define FC_NL_ASYNC_EVENT			0x0010
+#define FC_NL_ASYNC_EVENT			0x0100
 #define FC_NL_SC_GET_CONFIG_REQ			0x0020
 #define FC_NL_SC_SET_CONFIG_REQ			0x0030
 #define FC_NL_SC_DHCHAP_MAKE_CHALLENGE_REQ	0x0040
@@ -235,9 +235,10 @@ struct scsi_nl_hdr {
 	uint16_t msglen;
 } __attribute__((aligned(sizeof(uint64_t))));
 */
+
 struct fc_nl_sc_message {
-	struct scsi_nl_hdr snlh;              /* must be 1st element ! */
-	uint32_t host_no;
+	uint16_t msgtype;
+	uint16_t rsvd;
 	uint32_t tran_id;
 	uint32_t data_len;
 	uint8_t data[0];
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index c60a116..082dce7 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -291,7 +291,6 @@ extern struct class_device_attribute *lpfc_hba_attrs[];
 extern struct class_device_attribute *lpfc_vport_attrs[];
 extern struct scsi_host_template lpfc_template;
 extern struct class_device_attribute *lpfc_hba_attrs_no_npiv[];
-extern struct scsi_host_template lpfc_template_no_npiv;
 extern struct scsi_host_template lpfc_vport_template;
 extern struct fc_function_template lpfc_transport_functions;
 extern struct fc_function_template lpfc_vport_transport_functions;
@@ -322,8 +321,8 @@ void lpfc_dhchap_authenticate(struct Scsi_Host *, int , void *, uint32_t);
 int lpfc_start_node_authentication(struct lpfc_nodelist *);
 int lpfc_get_auth_config(struct lpfc_nodelist *, struct lpfc_name *);
 void lpfc_start_discovery(struct lpfc_vport *vport);
-
 void lpfc_start_authentication(struct lpfc_vport *, struct lpfc_nodelist *);
+int lpfc_rcv_nl_msg(struct Scsi_Host *, void *, uint32_t, uint32_t);
 
 extern void lpfc_debugfs_initialize(struct lpfc_vport *);
 extern void lpfc_debugfs_terminate(struct lpfc_vport *);
@@ -337,6 +336,7 @@ extern uint8_t lpfc_security_service_state;
 extern spinlock_t fc_security_user_lock;
 extern struct list_head fc_security_user_list;
 extern int fc_service_state;
+void lpfc_rcv_nl_event(struct notifier_block *, unsigned long , void *);
 
 /* Interface exported by fabric iocb scheduler */
 int lpfc_issue_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 786fc8a..6303207 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -165,7 +165,11 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
 		/* For ELS_REQUEST64_CR, use the VPI by default */
 		icmd->ulpContext = vport->vpi;
 		icmd->ulpCt_h = 0;
-		icmd->ulpCt_l = 1;
+		/* The CT field must be 0=INVALID_RPI for the ECHO cmd */
+		if (elscmd == ELS_CMD_ECHO)
+			icmd->ulpCt_l = 0; /* context = invalid RPI */
+		else
+			icmd->ulpCt_l = 1; /* context = VPI */
 	}
 
 	bpl = (struct ulp_bde64 *) pbuflist->virt;
@@ -1972,6 +1976,15 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 	case IOSTAT_LOCAL_REJECT:
 		switch ((irsp->un.ulpWord[4] & 0xff)) {
 		case IOERR_LOOP_OPEN_FAILURE:
+			if (cmd == ELS_CMD_FLOGI) {
+				if (PCI_DEVICE_ID_HORNET ==
+					phba->pcidev->device) {
+					phba->fc_topology = TOPOLOGY_LOOP;
+					phba->pport->fc_myDID = 0;
+					phba->alpa_map[0] = 0;
+					phba->alpa_map[1] = 0;
+				}
+			}
 			if (cmd == ELS_CMD_PLOGI && cmdiocb->retry == 0)
 				delay = 1000;
 			retry = 1;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 0a0b9bb..ea5de1a 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1837,6 +1837,40 @@ lpfc_disable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 	lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state,
 				NLP_STE_UNUSED_NODE);
 }
+/**
+ * lpfc_initialize_node: Initialize all fields of node object.
+ * @vport: Pointer to Virtual Port object.
+ * @ndlp: Pointer to FC node object.
+ * @did: FC_ID of the node.
+ *	This function is always called when node object need to
+ * be initialized. It initializes all the fields of the node
+ * object.
+ **/
+static inline void
+lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+	uint32_t did)
+{
+	INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp);
+	INIT_LIST_HEAD(&ndlp->dev_loss_evt.evt_listp);
+	INIT_LIST_HEAD(&ndlp->els_reauth_evt.evt_listp);
+	init_timer(&ndlp->nlp_initiator_tmr);
+	ndlp->nlp_initiator_tmr.function = lpfc_dev_loss_delay;
+	ndlp->nlp_initiator_tmr.data = (unsigned long)ndlp;
+	init_timer(&ndlp->nlp_delayfunc);
+	ndlp->nlp_delayfunc.function = lpfc_els_retry_delay;
+	ndlp->nlp_delayfunc.data = (unsigned long)ndlp;
+	ndlp->nlp_DID = did;
+	init_timer(&ndlp->nlp_reauth_tmr);
+	ndlp->nlp_reauth_tmr.function = lpfc_reauth_node;
+	ndlp->nlp_reauth_tmr.data = (unsigned long)ndlp;
+	ndlp->unreg_time = jiffies;
+	ndlp->vport = vport;
+	ndlp->nlp_sid = NLP_NO_SID;
+	kref_init(&ndlp->kref);
+	NLP_INT_NODE_ACT(ndlp);
+	atomic_set(&ndlp->cmd_pending, 0);
+	ndlp->cmd_qdepth = LPFC_MAX_TGT_QDEPTH;
+}
 
 struct lpfc_nodelist *
 lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
@@ -1877,28 +1911,7 @@ lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 	/* re-initialize ndlp except of ndlp linked list pointer */
 	memset((((char *)ndlp) + sizeof (struct list_head)), 0,
 		sizeof (struct lpfc_nodelist) - sizeof (struct list_head));
-	INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp);
-	INIT_LIST_HEAD(&ndlp->dev_loss_evt.evt_listp);
-	INIT_LIST_HEAD(&ndlp->els_reauth_evt.evt_listp);
-
-	init_timer(&ndlp->nlp_initiator_tmr);
-	ndlp->nlp_initiator_tmr.function = lpfc_dev_loss_delay;
-	ndlp->nlp_initiator_tmr.data = (unsigned long)ndlp;
-	init_timer(&ndlp->nlp_delayfunc);
-	ndlp->nlp_delayfunc.function = lpfc_els_retry_delay;
-	ndlp->nlp_delayfunc.data = (unsigned long)ndlp;
-
-	init_timer(&ndlp->nlp_reauth_tmr);
-	ndlp->nlp_reauth_tmr.function = lpfc_reauth_node;
-	ndlp->nlp_reauth_tmr.data = (unsigned long)ndlp;
-
-	ndlp->unreg_time = jiffies;
-	ndlp->nlp_DID = did;
-	ndlp->vport = vport;
-	ndlp->nlp_sid = NLP_NO_SID;
-	/* ndlp management re-initialize */
-	kref_init(&ndlp->kref);
-	NLP_INT_NODE_ACT(ndlp);
+	lpfc_initialize_node(vport, ndlp, did);
 
 	spin_unlock_irqrestore(&phba->ndlp_lock, flags);
 
@@ -2511,7 +2524,8 @@ lpfc_disc_list_loopmap(struct lpfc_vport *vport)
 			alpa = lpfcAlpaArray[index];
 			if ((vport->fc_myDID & 0xff) == alpa)
 				continue;
-			lpfc_setup_disc_node(vport, alpa);
+			if (!(phba->link_flag & LS_LOOPBACK_MODE))
+				lpfc_setup_disc_node(vport, alpa);
 		}
 	}
 	return;
@@ -3196,29 +3210,8 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 	      uint32_t did)
 {
 	memset(ndlp, 0, sizeof (struct lpfc_nodelist));
-	INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp);
-	INIT_LIST_HEAD(&ndlp->dev_loss_evt.evt_listp);
-	INIT_LIST_HEAD(&ndlp->els_reauth_evt.evt_listp);
-	init_timer(&ndlp->nlp_initiator_tmr);
-	ndlp->nlp_initiator_tmr.function = lpfc_dev_loss_delay;
-	ndlp->nlp_initiator_tmr.data = (unsigned long)ndlp;
-	init_timer(&ndlp->nlp_delayfunc);
-	ndlp->nlp_delayfunc.function = lpfc_els_retry_delay;
-	ndlp->nlp_delayfunc.data = (unsigned long)ndlp;
-
-	init_timer(&ndlp->nlp_reauth_tmr);
-	ndlp->nlp_reauth_tmr.function = lpfc_reauth_node;
-	ndlp->nlp_reauth_tmr.data = (unsigned long)ndlp;
-
-	ndlp->unreg_time = jiffies;
-	ndlp->nlp_DID = did;
-	ndlp->vport = vport;
-	ndlp->nlp_sid = NLP_NO_SID;
+	lpfc_initialize_node(vport, ndlp, did);
 	INIT_LIST_HEAD(&ndlp->nlp_listp);
-	kref_init(&ndlp->kref);
-	NLP_INT_NODE_ACT(ndlp);
-	atomic_set(&ndlp->cmd_pending, 0);
-	ndlp->cmd_qdepth = LPFC_MAX_TGT_QDEPTH;
 
 	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE,
 		"node init:       did:x%x",
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 8ef0f9c..c5de318 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -2576,10 +2576,17 @@ typedef struct {
 
 	uint32_t pcbLow;       /* bit 31:0  of memory based port config block */
 	uint32_t pcbHigh;      /* bit 63:32 of memory based port config block */
-	uint32_t hbainit[6];
+	uint32_t hbainit[5];
+#ifdef __BIG_ENDIAN_BITFIELD
+	uint32_t hps	   :  1; /* bit 31 word9 Host Pointer in slim */
+	uint32_t rsvd	   : 31; /* least significant 31 bits of word 9 */
+#else   /*  __LITTLE_ENDIAN */
+	uint32_t rsvd      : 31; /* least significant 31 bits of word 9 */
+	uint32_t hps	   :  1; /* bit 31 word9 Host Pointer in slim */
+#endif
 
 #ifdef __BIG_ENDIAN_BITFIELD
-	uint32_t rsvd      : 24;  /* Reserved                             */
+	uint32_t rsvd1     : 24;  /* Reserved                             */
 	uint32_t cmv	   :  1;  /* Configure Max VPIs                   */
 	uint32_t ccrp      :  1;  /* Config Command Ring Polling          */
 	uint32_t csah      :  1;  /* Configure Synchronous Abort Handling */
@@ -2597,7 +2604,7 @@ typedef struct {
 	uint32_t csah      :  1;  /* Configure Synchronous Abort Handling */
 	uint32_t ccrp      :  1;  /* Config Command Ring Polling          */
 	uint32_t cmv	   :  1;  /* Configure Max VPIs                   */
-	uint32_t rsvd      : 24;  /* Reserved                             */
+	uint32_t rsvd1     : 24;  /* Reserved                             */
 #endif
 #ifdef __BIG_ENDIAN_BITFIELD
 	uint32_t rsvd2     : 24;  /* Reserved                             */
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index e97148e..cd6d59f 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -44,24 +44,22 @@
 #include "lpfc_vport.h"
 #include "lpfc_version.h"
 #include "lpfc_auth_access.h"
-#include "lpfc_ioctl.h"
 #include "lpfc_security.h"
 #include "lpfc_compat.h"
 
 #include <net/sock.h>
 #include <linux/netlink.h>
 
-extern struct notifier_block lpfc_fc_netlink_notifier;
-extern char security_work_q_name[KOBJ_NAME_LEN];
+/* vendor ID used in SCSI netlink calls */
+#define LPFC_NL_VENDOR_ID (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX)
+const char *security_work_q_name = "fc_sc_wq";
 extern struct workqueue_struct *security_work_q;
-extern struct sock *fc_nl_sock;
 extern struct list_head fc_security_user_list;
 extern int fc_service_state;
 void lpfc_fc_sc_security_online(struct work_struct *work);
 void lpfc_fc_sc_security_offline(struct work_struct *work);
-void lpfc_fc_nl_rcv(struct sock *sk, int len);
 int lpfc_fc_queue_security_work(struct lpfc_vport *, struct work_struct *);
-int lpfc_fc_nl_rcv_nl_event(struct notifier_block *, unsigned long , void *);
+#include "lpfc_ioctl.h"
 static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
 static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *);
 static int lpfc_post_rcv_buf(struct lpfc_hba *);
@@ -870,8 +868,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
 		fc_host_post_vendor_event(shost, fc_get_event_number(),
 					  sizeof(temp_event_data),
 					  (char *) &temp_event_data,
-					  SCSI_NL_VID_TYPE_PCI
-					  | PCI_VENDOR_ID_EMULEX);
+					  LPFC_NL_VENDOR_ID);
 
 		spin_lock_irq(&phba->hbalock);
 		phba->over_temp_state = HBA_OVER_TEMP;
@@ -893,7 +890,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
 		shost = lpfc_shost_from_vport(vport);
 		fc_host_post_vendor_event(shost, fc_get_event_number(),
 				sizeof(event_data), (char *) &event_data,
-				SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
+				LPFC_NL_VENDOR_ID);
 
 		lpfc_offline_eratt(phba);
 	}
@@ -1601,8 +1598,15 @@ lpfc_cleanup(struct lpfc_vport *vport)
 void
 lpfc_stop_vport_timers(struct lpfc_vport *vport)
 {
+	struct fc_security_request *fc_sc_req;
 	del_timer_sync(&vport->els_tmofunc);
 	del_timer_sync(&vport->fc_fdmitmo);
+	while (!list_empty(&vport->sc_response_wait_queue)) {
+		fc_sc_req = list_get_first(&vport->sc_response_wait_queue,
+					   struct fc_security_request, rlist);
+		del_timer_sync(&fc_sc_req->timer);
+		kfree(fc_sc_req);
+	}
 	lpfc_can_disctmo(vport);
 	return;
 }
@@ -1815,12 +1819,8 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
 		shost = scsi_host_alloc(&lpfc_vport_template,
 					sizeof(struct lpfc_vport));
 	else
-		if (phba->cfg_enable_npiv)
-			shost = scsi_host_alloc(&lpfc_template,
-						sizeof(struct lpfc_vport));
-		else
-			shost = scsi_host_alloc(&lpfc_template_no_npiv,
-						sizeof(struct lpfc_vport));
+		shost = scsi_host_alloc(&lpfc_template,
+					sizeof(struct lpfc_vport));
 	if (!shost)
 		goto out;
 
@@ -2308,14 +2308,14 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
 
 	shost = lpfc_shost_from_vport(vport);
 
-	if ((lpfc_get_security_enabled)(shost)){
+	if ((lpfc_get_security_enabled)(shost)) {
 		unsigned long flags;
+		/* Triggers fcauthd to register if it is running */
+		fc_host_post_event(shost, fc_get_event_number(),
+				   FCH_EVT_PORT_ONLINE, shost->host_no);
 		spin_lock_irqsave(&fc_security_user_lock, flags);
-
 		list_add_tail(&vport->sc_users, &fc_security_user_list);
-
 		spin_unlock_irqrestore(&fc_security_user_lock, flags);
-
 		if (fc_service_state == FC_SC_SERVICESTATE_ONLINE) {
 			lpfc_fc_queue_security_work(vport,
 				&vport->sc_online_work);
@@ -2796,18 +2796,15 @@ lpfc_init(void)
 			return -ENOMEM;
 		}
 	}
-
-	error = netlink_register_notifier(&lpfc_fc_netlink_notifier);
+	else
+		lpfc_template.shost_attrs = lpfc_hba_attrs_no_npiv;
+	error = scsi_nl_add_driver(LPFC_NL_VENDOR_ID, &lpfc_template,
+				   lpfc_rcv_nl_msg, lpfc_rcv_nl_event);
 	if (error)
 		goto out_release_transport;
-	fc_nl_sock = netlink_kernel_create(NETLINK_FCTRANSPORT, FC_NL_GROUP_CNT,
-					   lpfc_fc_nl_rcv, THIS_MODULE);
-	if (!fc_nl_sock)
-		goto out_unregister_notifier;
-	snprintf(security_work_q_name, KOBJ_NAME_LEN, "fc_sc_wq");
 	security_work_q = create_singlethread_workqueue(security_work_q_name);
 	if (!security_work_q)
-		goto out_sock_release;
+		goto out_remove_nl;
 	INIT_LIST_HEAD(&fc_security_user_list);
 	error = pci_register_driver(&lpfc_driver);
 	if (error)
@@ -2823,11 +2820,8 @@ out_pci_unregister:
 out_destroy_workqueue:
 	destroy_workqueue(security_work_q);
 	security_work_q = NULL;
-out_sock_release:
-	sock_release(fc_nl_sock->sk_socket);
-	fc_nl_sock = NULL;
-out_unregister_notifier:
-	netlink_unregister_notifier(&lpfc_fc_netlink_notifier);
+out_remove_nl:
+	scsi_nl_remove_driver(LPFC_NL_VENDOR_ID);
 out_release_transport:
 	fc_release_transport(lpfc_transport_template);
 	if (lpfc_enable_npiv)
@@ -2843,11 +2837,7 @@ lpfc_exit(void)
 	if (security_work_q)
 		destroy_workqueue(security_work_q);
 	security_work_q = NULL;
-	if (fc_nl_sock) {
-		sock_release(fc_nl_sock->sk_socket);
-		netlink_unregister_notifier(&lpfc_fc_netlink_notifier);
-		fc_nl_sock = NULL;
-	}
+	scsi_nl_remove_driver(LPFC_NL_VENDOR_ID);
 	fc_release_transport(lpfc_transport_template);
 	if (lpfc_enable_npiv)
 		fc_release_transport(lpfc_vport_transport_template);
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 3da2f34..39eda2c 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -739,6 +739,9 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 	mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
 	mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
 
+	/* Always Host Group Pointer is in SLIM */
+	mb->un.varCfgPort.hps = 1;
+
 	/* If HBA supports SLI=3 ask for it */
 
 	if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) {
diff --git a/drivers/scsi/lpfc/lpfc_menlo.c b/drivers/scsi/lpfc/lpfc_menlo.c
index cb30091..bc3f8a2 100644
--- a/drivers/scsi/lpfc/lpfc_menlo.c
+++ b/drivers/scsi/lpfc/lpfc_menlo.c
@@ -42,6 +42,7 @@
 #include "lpfc_auth_access.h"
 
 #define MENLO_CMD_FW_DOWNLOAD                   0x00000002
+#define MENLO_CMD_LOOPBACK                   	0x00000014
 
 static void lpfc_menlo_iocb_timeout_cmpl(struct lpfc_hba *,
 			struct lpfc_iocbq *, struct lpfc_iocbq *);
@@ -542,14 +543,15 @@ lpfc_menlo_write(struct lpfc_hba *phba,
 	}
 
 	if ((count + sysfs_menlo->cr.offset) > sysfs_menlo->cmdhdr.cmdsize) {
-		if ( sysfs_menlo->cmdhdr.cmdsize != 4) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+		if (sysfs_menlo->cmdhdr.cmdsize >=
+			sizeof(struct lpfc_sysfs_menlo_hdr)) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
 			"1213 FCoE cmd overflow: off %d + cnt %d > cmdsz %d\n",
-			(int)sysfs_menlo->cr.offset,
-			(int)count,
-			(int)sysfs_menlo->cmdhdr.cmdsize);
-		sysfs_menlo_idle(phba, sysfs_menlo);
-		return -ERANGE;
+				(int)sysfs_menlo->cr.offset,
+				(int)count,
+				(int)sysfs_menlo->cmdhdr.cmdsize);
+			sysfs_menlo_idle(phba, sysfs_menlo);
+			return -ERANGE;
 		}
 	}
 
@@ -688,6 +690,16 @@ lpfc_menlo_write(struct lpfc_hba *phba,
 		} else
 			memcpy((uint8_t *) mlast->dma.virt, buf, count);
 
+		if (sysfs_menlo->cmdhdr.cmd == MENLO_CMD_LOOPBACK) {
+			if (mlast) {
+				tmpptr = (uint32_t *)mlast->dma.virt;
+				if (*(tmpptr+2))
+					phba->link_flag |= LS_LOOPBACK_MODE;
+				else
+					phba->link_flag &= ~LS_LOOPBACK_MODE;
+			}
+		}
+
 		if (sysfs_menlo->cmdhdr.cmd == MENLO_CMD_FW_DOWNLOAD
 			&& genreq->offset < hdr_offset) {
 			if (sysfs_menlo->cr.indmp
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 0e0ee86..b21c708 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -626,7 +626,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 
 	lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
 	lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
-	atomic_dec(&pnode->cmd_pending);
+	if (pnode && NLP_CHK_NODE_ACT(pnode))
+		atomic_dec(&pnode->cmd_pending);
 
 	if (lpfc_cmd->status) {
 		if (lpfc_cmd->status == IOSTAT_LOCAL_REJECT &&
@@ -691,23 +692,31 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 	   time_after(jiffies, lpfc_cmd->start_time +
 		msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) {
 		spin_lock_irqsave(sdev->host->host_lock, flags);
-		if ((pnode->cmd_qdepth > atomic_read(&pnode->cmd_pending) &&
-		    (atomic_read(&pnode->cmd_pending) > LPFC_MIN_TGT_QDEPTH) &&
-		    ((cmd->cmnd[0] == READ_10) || (cmd->cmnd[0] == WRITE_10))))
-			pnode->cmd_qdepth = atomic_read(&pnode->cmd_pending);
-
-		pnode->last_change_time = jiffies;
+		if (pnode && NLP_CHK_NODE_ACT(pnode)) {
+			if (pnode->cmd_qdepth >
+				atomic_read(&pnode->cmd_pending) &&
+				(atomic_read(&pnode->cmd_pending) >
+				LPFC_MIN_TGT_QDEPTH) &&
+				((cmd->cmnd[0] == READ_10) ||
+				(cmd->cmnd[0] == WRITE_10)))
+				pnode->cmd_qdepth =
+					atomic_read(&pnode->cmd_pending);
+
+			pnode->last_change_time = jiffies;
+		}
 		spin_unlock_irqrestore(sdev->host->host_lock, flags);
-	} else if ((pnode->cmd_qdepth < LPFC_MAX_TGT_QDEPTH) &&
+	} else if (pnode && NLP_CHK_NODE_ACT(pnode)) {
+		if ((pnode->cmd_qdepth < LPFC_MAX_TGT_QDEPTH) &&
 		   time_after(jiffies, pnode->last_change_time +
-			msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) {
-		spin_lock_irqsave(sdev->host->host_lock, flags);
-		pnode->cmd_qdepth += pnode->cmd_qdepth *
-			LPFC_TGTQ_RAMPUP_PCENT / 100;
-		if (pnode->cmd_qdepth > LPFC_MAX_TGT_QDEPTH)
-			pnode->cmd_qdepth = LPFC_MAX_TGT_QDEPTH;
-		pnode->last_change_time = jiffies;
-		spin_unlock_irqrestore(sdev->host->host_lock, flags);
+			      msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) {
+			spin_lock_irqsave(sdev->host->host_lock, flags);
+			pnode->cmd_qdepth += pnode->cmd_qdepth *
+				LPFC_TGTQ_RAMPUP_PCENT / 100;
+			if (pnode->cmd_qdepth > LPFC_MAX_TGT_QDEPTH)
+				pnode->cmd_qdepth = LPFC_MAX_TGT_QDEPTH;
+			pnode->last_change_time = jiffies;
+			spin_unlock_irqrestore(sdev->host->host_lock, flags);
+		}
 	}
 
 	lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
@@ -1116,7 +1125,8 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 		cmnd->result = ScsiResult(DID_TRANSPORT_DISRUPTED, 0);
 		goto out_fail_command;
 	}
-	if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth)
+	if (vport->cfg_max_scsicmpl_time &&
+		(atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth))
 		goto out_host_busy;
 
 	lpfc_cmd = lpfc_get_scsi_buf(phba);
@@ -1584,25 +1594,6 @@ struct scsi_host_template lpfc_template = {
 	.max_sectors		= 0xFFFF,
 };
 
-struct scsi_host_template lpfc_template_no_npiv = {
-	.module			= THIS_MODULE,
-	.name			= LPFC_DRIVER_NAME,
-	.info			= lpfc_info,
-	.queuecommand		= lpfc_queuecommand,
-	.eh_abort_handler	= lpfc_abort_handler,
-	.eh_device_reset_handler= lpfc_device_reset_handler,
-	.eh_bus_reset_handler	= lpfc_bus_reset_handler,
-	.slave_alloc		= lpfc_slave_alloc,
-	.slave_configure	= lpfc_slave_configure,
-	.slave_destroy		= lpfc_slave_destroy,
-	.this_id		= -1,
-	.sg_tablesize		= LPFC_DEFAULT_SG_SEG_CNT,
-	.cmd_per_lun		= LPFC_CMD_PER_LUN,
-	.use_clustering		= ENABLE_CLUSTERING,
-	.shost_attrs		= lpfc_hba_attrs_no_npiv,
-	.max_sectors		= 0xFFFF,
-};
-
 struct scsi_host_template lpfc_vport_template = {
 	.module			= THIS_MODULE,
 	.name			= LPFC_DRIVER_NAME,
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index de3cddf..55f5f23 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.2.0.30"
+#define LPFC_DRIVER_VERSION "8.2.0.33.2p"
 
 #define LPFC_DRIVER_NAME "lpfc"
 
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index ef42e04..9a449d2 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -617,8 +617,6 @@ lpfc_vport_delete(struct Scsi_Host *shost)
 		}
 		vport->unreg_vpi_cmpl = VPORT_INVAL;
 		timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
-		if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
-			goto skip_logo;
 		if (!lpfc_issue_els_npiv_logo(vport, ndlp))
 			while (vport->unreg_vpi_cmpl == VPORT_INVAL && timeout)
 				timeout = schedule_timeout(timeout);