changeset 11240:530d474a5d9e

6904131 COMSTAR: Fix unsolicited exchange abort issue 6904115 Turn off DMA handle checking in the fm-capable config parameter 6904120 IO hang during diskomizer test and pci errors during UE register access in FCoE adapter 6901958 memory leak in emlxs_mem_alloc and emlxs_sli3_online
author Sukumar Swaminathan <Sukumar.Swaminathan@Sun.COM>
date Thu, 03 Dec 2009 10:09:44 -0800
parents 75c9bb2d7547
children 13b9f5cc13e3
files usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_clock.c usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dfc.c usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fcp.c usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fct.c usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_node.c usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_solaris.c usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_config.h usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_dfclib.h usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_extern.h usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fc.h usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fcio.h usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_hw.h usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_version.h
diffstat 16 files changed, 421 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_clock.c	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_clock.c	Thu Dec 03 10:09:44 2009 -0800
@@ -146,14 +146,6 @@
 		return;
 	}
 
-	/* DEBUG - re-examine this path for SLI4 later */
-	if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) {
-		/* Check for linkup timeout */
-		emlxs_timer_check_linkup(hba);
-
-		return;
-	}
-
 	bzero((void *)flag, sizeof (flag));
 
 	/* Check SLI level timeouts */
@@ -884,7 +876,7 @@
 	mutex_exit(&EMLXS_PORT_LOCK);
 
 	/* Try to send clear link attention, if needed */
-	if ((send_clear_la == 1) &&
+	if ((hba->sli_mode < EMLXS_HBA_SLI4_MODE) && (send_clear_la == 1) &&
 	    (mbox = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
 		mutex_enter(&EMLXS_PORT_LOCK);
 
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dfc.c	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dfc.c	Thu Dec 03 10:09:44 2009 -0800
@@ -10289,6 +10289,13 @@
 		return (DFC_FCOE_NOTSUPPORTED);
 	}
 
+	if (hba->state != FC_READY) {
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
+		    "%s: HBA not ready.", emlxs_dfc_xlate(dfc->cmd));
+
+		return (DFC_DRV_ERROR);
+	}
+
 	size = sizeof (DFC_FCoEFCFList_t) +
 	    hba->sli.sli4.FCFICount * sizeof (DFC_FCoEFCFInfo_t);
 	fcflist = (DFC_FCoEFCFList_t *)kmem_zalloc(size, KM_SLEEP);
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c	Thu Dec 03 10:09:44 2009 -0800
@@ -4593,6 +4593,10 @@
 
 	vpd = &VPD;
 
+	if (hba->model_info.chip == EMLXS_BE_CHIP) {
+		return (EMLXS_OP_NOT_SUP);
+	}
+
 	if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) {
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
 		    "emlxs_boot_code_disable: Unable to read wake up parms.");
@@ -4644,6 +4648,10 @@
 
 	vpd = &VPD;
 
+	if (hba->model_info.chip == EMLXS_BE_CHIP) {
+		return (FC_SUCCESS);
+	}
+
 	/* Read the wakeup parms */
 	if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 0)) {
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
@@ -4709,6 +4717,10 @@
 {
 	emlxs_port_t *port = &PPORT;
 
+	if (hba->model_info.chip == EMLXS_BE_CHIP) {
+		return (FC_SUCCESS);
+	}
+
 	/* Read the wakeup parms */
 	if (emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1)) {
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fcp.c	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fcp.c	Thu Dec 03 10:09:44 2009 -0800
@@ -3743,7 +3743,7 @@
 
 /*
  * Issue an ABORT_XRI_CN iocb command to abort an FCP command already issued.
- * This must be called while holding the EMLXS_FCCTAB_LOCK
+ * This must be called while holding the EMLXS_FCTAB_LOCK
  */
 extern IOCBQ *
 emlxs_create_abort_xri_cn(emlxs_port_t *port, NODELIST *ndlp,
@@ -3809,6 +3809,7 @@
 } /* emlxs_create_abort_xri_cn() */
 
 
+/* This must be called while holding the EMLXS_FCTAB_LOCK */
 extern IOCBQ *
 emlxs_create_abort_xri_cx(emlxs_port_t *port, NODELIST *ndlp, uint16_t xid,
     CHANNEL *cp, uint8_t class, int32_t flag)
@@ -3863,7 +3864,7 @@
 
 
 
-/* This must be called while holding the EMLXS_FCCTAB_LOCK */
+/* This must be called while holding the EMLXS_FCTAB_LOCK */
 extern IOCBQ *
 emlxs_create_close_xri_cn(emlxs_port_t *port, NODELIST *ndlp,
     uint16_t iotag, CHANNEL *cp)
@@ -3927,7 +3928,7 @@
 } /* emlxs_create_close_xri_cn() */
 
 
-/* This must be called while holding the EMLXS_FCCTAB_LOCK */
+/* This must be called while holding the EMLXS_FCTAB_LOCK */
 extern IOCBQ *
 emlxs_create_close_xri_cx(emlxs_port_t *port, NODELIST *ndlp, uint16_t xid,
     CHANNEL *cp)
@@ -3980,16 +3981,122 @@
 } /* emlxs_create_close_xri_cx() */
 
 
+#ifdef SFCT_SUPPORT
+void
+emlxs_abort_fct_exchange(emlxs_hba_t *hba, emlxs_port_t *port, uint32_t rxid)
+{
+	CHANNEL *cp;
+	IOCBQ *iocbq;
+	IOCB *iocb;
+
+	if (rxid == 0 || rxid == 0xFFFF) {
+		return;
+	}
+
+	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
+		    "Aborting FCT exchange: xid=%x", rxid);
+
+		if (emlxs_sli4_unreserve_xri(hba, rxid) == 0) {
+			/* We have no way to abort unsolicited exchanges */
+			/* that we have not responded to at this time */
+			/* So we will return for now */
+			return;
+		}
+	}
+
+	cp = &hba->chan[hba->channel_fcp];
+
+	mutex_enter(&EMLXS_FCTAB_LOCK);
+
+	/* Create the abort IOCB */
+	if (hba->state >= FC_LINK_UP) {
+		iocbq = emlxs_create_abort_xri_cx(port, NULL, rxid, cp,
+		    CLASS3, ABORT_TYPE_ABTS);
+	} else {
+		iocbq = emlxs_create_close_xri_cx(port, NULL, rxid, cp);
+	}
+
+	mutex_exit(&EMLXS_FCTAB_LOCK);
+
+	if (iocbq) {
+		iocb = &iocbq->iocb;
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
+		    "Aborting FCT exchange: xid=%x iotag=%x", rxid,
+		    iocb->ULPIOTAG);
+
+		EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq);
+	}
+
+} /* emlxs_abort_fct_exchange() */
+#endif /* SFCT_SUPPORT */
+
+
+void
+emlxs_abort_els_exchange(emlxs_hba_t *hba, emlxs_port_t *port, uint32_t rxid)
+{
+	CHANNEL *cp;
+	IOCBQ *iocbq;
+	IOCB *iocb;
+
+	if (rxid == 0 || rxid == 0xFFFF) {
+		return;
+	}
+
+	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
+
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
+		    "Aborting ELS exchange: xid=%x", rxid);
+
+		if (emlxs_sli4_unreserve_xri(hba, rxid) == 0) {
+			/* We have no way to abort unsolicited exchanges */
+			/* that we have not responded to at this time */
+			/* So we will return for now */
+			return;
+		}
+	}
+
+	cp = &hba->chan[hba->channel_els];
+
+	mutex_enter(&EMLXS_FCTAB_LOCK);
+
+	/* Create the abort IOCB */
+	if (hba->state >= FC_LINK_UP) {
+		iocbq = emlxs_create_abort_xri_cx(port, NULL, rxid, cp,
+		    CLASS3, ABORT_TYPE_ABTS);
+	} else {
+		iocbq = emlxs_create_close_xri_cx(port, NULL, rxid, cp);
+	}
+
+	mutex_exit(&EMLXS_FCTAB_LOCK);
+
+	if (iocbq) {
+		iocb = &iocbq->iocb;
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
+		    "Aborting ELS exchange: xid=%x iotag=%x", rxid,
+		    iocb->ULPIOTAG);
+
+		EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq);
+	}
+
+} /* emlxs_abort_els_exchange() */
+
+
 void
 emlxs_abort_ct_exchange(emlxs_hba_t *hba, emlxs_port_t *port, uint32_t rxid)
 {
 	CHANNEL *cp;
 	IOCBQ *iocbq;
-
-	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
-	    "Aborting CT exchange: xid=%x", rxid);
+	IOCB *iocb;
+
+	if (rxid == 0 || rxid == 0xFFFF) {
+		return;
+	}
 
 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
+		    "Aborting CT exchange: xid=%x", rxid);
+
 		if (emlxs_sli4_unreserve_xri(hba, rxid) == 0) {
 			/* We have no way to abort unsolicited exchanges */
 			/* that we have not responded to at this time */
@@ -4000,23 +4107,31 @@
 
 	cp = &hba->chan[hba->channel_ct];
 
+	mutex_enter(&EMLXS_FCTAB_LOCK);
+
 	/* Create the abort IOCB */
 	if (hba->state >= FC_LINK_UP) {
-		iocbq =
-		    emlxs_create_abort_xri_cx(port, NULL, rxid, cp, CLASS3,
-		    ABORT_TYPE_ABTS);
+		iocbq = emlxs_create_abort_xri_cx(port, NULL, rxid, cp,
+		    CLASS3, ABORT_TYPE_ABTS);
 	} else {
 		iocbq = emlxs_create_close_xri_cx(port, NULL, rxid, cp);
 	}
 
+	mutex_exit(&EMLXS_FCTAB_LOCK);
+
 	if (iocbq) {
+		iocb = &iocbq->iocb;
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
+		    "Aborting CT exchange: xid=%x iotag=%x", rxid,
+		    iocb->ULPIOTAG);
+
 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq);
 	}
 
 } /* emlxs_abort_ct_exchange() */
 
 
-/* This must be called while holding the EMLXS_FCCTAB_LOCK */
+/* This must be called while holding the EMLXS_FCTAB_LOCK */
 static void
 emlxs_sbp_abort_add(emlxs_port_t *port, emlxs_buf_t *sbp, Q *abort,
     uint8_t *flag, emlxs_buf_t *fpkt)
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fct.c	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fct.c	Thu Dec 03 10:09:44 2009 -0800
@@ -92,7 +92,8 @@
     CHANNEL *cp, IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
 static uint32_t emlxs_fct_process_unsol_plogi(emlxs_port_t *port,
     CHANNEL *cp, IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
-static fct_status_t emlxs_fct_pkt_abort(emlxs_port_t *port, emlxs_buf_t *sbp);
+static uint32_t emlxs_fct_pkt_abort_txq(emlxs_port_t *port,
+    emlxs_buf_t *cmd_sbp);
 static fct_status_t emlxs_fct_send_qfull_reply(emlxs_port_t *port,
     emlxs_node_t *ndlp, uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd);
 static void emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type);
@@ -1919,7 +1920,7 @@
 		    "emlxs_fct_send_cmd_rsp: Invalid cmd type found. type=%x",
 		    fct_cmd->cmd_type);
 
-		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
+		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
 		/* mutex_exit(&cmd_sbp->fct_mtx); */
 
 		return (FCT_FAILURE);
@@ -1932,7 +1933,7 @@
 	    "Unable to handle FCT_IOF_FORCE_FCA_DONE. type=%x",
 	    fct_cmd->cmd_type);
 
-	emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
+	emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
 	/* mutex_exit(&cmd_sbp->fct_mtx); */
 
 	return (FCT_FAILURE);
@@ -2273,7 +2274,7 @@
 
 		remote_port->rp_handle = ndlp->nlp_Rpi;
 
-		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
+		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
 		/* mutex_exit(&cmd_sbp->fct_mtx); */
 
 		TGTPORTSTAT.FctPortRegister++;
@@ -2287,7 +2288,7 @@
 
 		remote_port->rp_handle = FCT_HANDLE_NONE;
 
-		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
+		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
 		/* mutex_exit(&cmd_sbp->fct_mtx); */
 
 		TGTPORTSTAT.FctFailedPortRegister++;
@@ -2574,7 +2575,7 @@
 
 	if (EMLXS_SLI_PREP_FCT_IOCB(port, cmd_sbp, channel) != IOERR_SUCCESS) {
 
-		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
+		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
 		/* mutex_exit(&cmd_sbp->fct_mtx); */
 
 		return (FCT_BUSY);
@@ -2644,7 +2645,7 @@
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
 		    "emlxs_fct_send_fcp_status: Unable to allocate packet.");
 
-		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
+		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
 		/* mutex_exit(&cmd_sbp->fct_mtx); */
 
 		return (FCT_BUSY);
@@ -2740,7 +2741,7 @@
 		}
 		/* mutex_enter(&cmd_sbp->fct_mtx); */
 
-		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
+		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
 		/* mutex_exit(&cmd_sbp->fct_mtx); */
 
 		return (FCT_BUSY);
@@ -2970,7 +2971,7 @@
 
 		cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS;
 
-		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
+		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
 		/* mutex_exit(&cmd_sbp->fct_mtx); */
 
 #ifdef FCT_API_TRACE
@@ -3313,8 +3314,9 @@
 		return (1);
 	}
 
-	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "FLOGI: sid=0x%x %s",
-	    iocb->un.elsreq.remoteID, buffer);
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
+	    "FLOGI: sid=0x%x xid=%x %s",
+	    iocb->un.elsreq.remoteID, iocb->ULPIOTAG, buffer);
 
 	return (0);
 
@@ -3338,8 +3340,9 @@
 		return (1);
 	}
 
-	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "PLOGI: sid=0x%x %s",
-	    iocb->un.elsreq.remoteID, buffer);
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
+	    "PLOGI: sid=0x%x xid=%x %s",
+	    iocb->un.elsreq.remoteID, iocb->ULPIOTAG, buffer);
 
 	return (0);
 
@@ -4003,7 +4006,7 @@
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
 		    "emlxs_fct_send_els_rsp: Unable to allocate packet.");
 
-		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
+		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
 		/* mutex_exit(&cmd_sbp->fct_mtx); */
 
 		return (FCT_FAILURE);
@@ -4058,7 +4061,7 @@
 		}
 		/* mutex_enter(&cmd_sbp->fct_mtx); */
 
-		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
+		emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
 		/* mutex_exit(&cmd_sbp->fct_mtx); */
 
 		return (FCT_FAILURE);
@@ -4156,7 +4159,7 @@
 
 
 /* cmd_sbp->fct_mtx must be held to enter */
-uint32_t
+static uint32_t
 emlxs_fct_pkt_abort_txq(emlxs_port_t *port, emlxs_buf_t *cmd_sbp)
 {
 	emlxs_hba_t *hba = HBA;
@@ -4397,10 +4400,10 @@
 	}
 
 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
-	    "emlxs_fct_abort: HbaLink %d. "
-	    "xid=%x. cmd_sbp=%p state=%d flags=%x,%x,%x",
-	    hba->state, fct_cmd->cmd_rxid, cmd_sbp, cmd_sbp->fct_state, flags,
-	    cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
+	    "emlxs_fct_abort: hbastate=%x. "
+	    "xid=%x,%x cmd_sbp=%p fctstate=%d flags=%x,%x,%x",
+	    hba->state, fct_cmd->cmd_oxid, fct_cmd->cmd_rxid, cmd_sbp,
+	    cmd_sbp->fct_state, flags, cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
 
 	if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) {
 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, cmd_sbp->channel, 0);
@@ -4420,9 +4423,9 @@
 	switch (cmd_sbp->fct_state) {
 	/* These are currently owned by COMSTAR. */
 	/* They were last processed by emlxs_fct_cmd_post() */
-	case EMLXS_FCT_CMD_POSTED:
+	/* We have NO exchange resources associated with this IO. */
 	case EMLXS_FCT_OWNED:
-		goto abort_it_now;
+		goto abort_done;
 
 	/* These are on the unsol waitQ in the driver */
 	case EMLXS_FCT_CMD_WAITQ:
@@ -4453,7 +4456,24 @@
 		}
 		mutex_exit(&EMLXS_PORT_LOCK);
 
-		goto abort_it_now;
+		/*FALLTHROUGH*/
+
+	/* These are currently owned by COMSTAR. */
+	/* They were last processed by emlxs_fct_cmd_post() */
+	/* We have residual exchange resources associated with this IO */
+	case EMLXS_FCT_CMD_POSTED:
+		switch (fct_cmd->cmd_type) {
+		case FCT_CMD_FCP_XCHG: /* Unsol */
+			TGTPORTSTAT.FctOutstandingIO--;
+			emlxs_abort_fct_exchange(hba, port, fct_cmd->cmd_rxid);
+			break;
+
+		case FCT_CMD_RCVD_ELS: /* Unsol */
+			emlxs_abort_els_exchange(hba, port, fct_cmd->cmd_rxid);
+			break;
+		}
+
+		goto abort_done;
 
 	/* These are active in the driver */
 	/* They were last processed by emlxs_fct_cmd_release() */
@@ -4470,7 +4490,7 @@
 				TGTPORTSTAT.FctOutstandingIO--;
 			}
 
-			goto abort_it_now;
+			goto abort_done;
 		}
 
 		/* If we're not online, then all IO will be flushed anyway */
@@ -4579,7 +4599,7 @@
 
 	return (FCT_SUCCESS);
 
-abort_it_now:
+abort_done:
 
 	emlxs_fct_cmd_done(port, fct_cmd,
 	    EMLXS_FCT_ABORT_DONE);
@@ -4613,7 +4633,6 @@
 #endif /* FCT_API_TRACE */
 		MODSYM(fct_handle_event) (port->fct_port, FCT_EVENT_LINK_UP,
 		    0, 0);
-
 	} else {
 		if (!hba->ini_mode &&
 		    !(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_node.c	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_node.c	Thu Dec 03 10:09:44 2009 -0800
@@ -82,7 +82,7 @@
 			mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
 
 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_closed_msg,
-			    "node=%p did=%06x channel=%d. offline=%d set.",
+			    "node=%p did=%06x channel=%d. offline=%d update.",
 			    ndlp, ndlp->nlp_DID, channelno, timeout);
 
 		} else if (timeout) {
@@ -90,7 +90,7 @@
 			mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
 
 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_closed_msg,
-			    "node=%p did=%06x channel=%d. timeout=%d set.",
+			    "node=%p did=%06x channel=%d. timeout=%d update.",
 			    ndlp, ndlp->nlp_DID, channelno, timeout);
 		} else {
 			mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
@@ -106,8 +106,20 @@
 		ndlp->nlp_tics[channelno] = hba->timer_tics + timeout;
 		ndlp->nlp_flag[channelno] |= NLP_OFFLINE;
 
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_closed_msg,
+		    "node=%p did=%06x channel=%d. offline=%d set.",
+		    ndlp, ndlp->nlp_DID, channelno, timeout);
+
 	} else if (timeout) {
 		ndlp->nlp_tics[channelno] = hba->timer_tics + timeout;
+
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_closed_msg,
+		    "node=%p did=%06x channel=%d. timeout=%d set.",
+		    ndlp, ndlp->nlp_DID, channelno, timeout);
+	} else {
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_closed_msg,
+		    "node=%p did=%06x channel=%d.",
+		    ndlp, ndlp->nlp_DID, channelno);
 	}
 
 
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c	Thu Dec 03 10:09:44 2009 -0800
@@ -947,6 +947,12 @@
 		}
 	}
 
+	/* Free the buffers since we were polling */
+	(void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp);
+	mp = NULL;
+	(void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp1);
+	mp1 = NULL;
+
 	hba->channel_fcp = FC_FCP_RING;
 	hba->channel_els = FC_ELS_RING;
 	hba->channel_ip = FC_IP_RING;
@@ -1049,10 +1055,6 @@
 	}
 #endif /* MAX_RRDY_SUPPORT */
 
-	/* Free the buffer since we were polling */
-	(void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp);
-	mp = NULL;
-
 	/* Reuse mbq from previous mbox */
 	bzero(mbq, sizeof (MAILBOXQ));
 
@@ -1470,6 +1472,7 @@
 	 * The leadvile driver will now handle the FLOGI at the driver level
 	 */
 
+	(void) kmem_free((uint8_t *)mbq, sizeof (MAILBOXQ));
 	return (0);
 
 failed:
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c	Thu Dec 03 10:09:44 2009 -0800
@@ -623,7 +623,8 @@
 		    "FCOE info dumped. rsp_cnt=%d status=%x",
 		    mb->un.varDmp4.rsp_cnt, mb->mbxStatus);
 		(void) emlxs_parse_fcoe(hba,
-		    (uint8_t *)hba->sli.sli4.dump_region.virt, 0);
+		    (uint8_t *)hba->sli.sli4.dump_region.virt,
+		    mb->un.varDmp4.rsp_cnt);
 	}
 
 	/* Reuse mbq from previous mbox */
@@ -1454,6 +1455,12 @@
 	hba->sli.sli4.cfgFCOE.FCMap[1] = FCOE_FCF_MAP1;
 	hba->sli.sli4.cfgFCOE.FCMap[2] = FCOE_FCF_MAP2;
 
+	/* Cache the UE MASK registers value for UE error detection */
+	hba->sli.sli4.ue_mask_lo = ddi_get32(hba->pci_acc_handle,
+	    (uint32_t *)(hba->pci_addr + PCICFG_UE_MASK_LO_OFFSET));
+	hba->sli.sli4.ue_mask_hi = ddi_get32(hba->pci_acc_handle,
+	    (uint32_t *)(hba->pci_addr + PCICFG_UE_MASK_HI_OFFSET));
+
 	return (0);
 
 } /* emlxs_sli4_hba_init() */
@@ -3370,7 +3377,7 @@
 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
 			    "FCOE Async Event VLINK CLEAR %d: received ",
 			    fcoe->ref_index);
-			if (fcoe->ref_index == 0) {
+			if (fcoe->ref_index == hba->vpi_base) {
 				/*
 				 * Bounce the link to force rediscovery for
 				 * VPI 0.  We are ignoring this event for
@@ -4348,10 +4355,12 @@
 		iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL);
 
 		/* Set up an iotag using special Abort iotags */
+		mutex_enter(&EMLXS_FCTAB_LOCK);
 		if ((hba->fc_oor_iotag >= EMLXS_MAX_ABORT_TAG)) {
 			hba->fc_oor_iotag = hba->max_iotag;
 		}
 		iotag = hba->fc_oor_iotag++;
+		mutex_exit(&EMLXS_FCTAB_LOCK);
 
 		/* BLS ACC Response */
 		wqe = &iocbq->wqe;
@@ -6893,29 +6902,25 @@
 	emlxs_port_t *port = &PPORT;
 	uint32_t ue_h;
 	uint32_t ue_l;
-	uint32_t on1;
-	uint32_t on2;
 
 	if (hba->flag & FC_HARDWARE_ERROR) {
 		return;
 	}
 
-	on1 = ddi_get32(hba->pci_acc_handle,
-	    (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_ONLINE1));
-	on2 = ddi_get32(hba->pci_acc_handle,
-	    (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_ONLINE2));
-
-	if (on1 != 0xffffffff || on2 != 0xffffffff) {
-		ue_l = ddi_get32(hba->pci_acc_handle,
-		    (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_LO_OFFSET));
-		ue_h = ddi_get32(hba->pci_acc_handle,
-		    (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_HI_OFFSET));
-
+	ue_l = ddi_get32(hba->pci_acc_handle,
+	    (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_LO_OFFSET));
+	ue_h = ddi_get32(hba->pci_acc_handle,
+	    (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_HI_OFFSET));
+
+	if ((~hba->sli.sli4.ue_mask_lo & ue_l) ||
+	    (~hba->sli.sli4.ue_mask_hi & ue_h)) {
 		/* Unrecoverable error detected */
 		/* Shut the HBA down */
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_hardware_error_msg,
-		    "Host Error: ueLow:%08x ueHigh:%08x on1:%08x on2:%08x",
-		    ue_l, ue_h, on1, on2);
+		    "Host Error: ueLow:%08x ueHigh:%08x maskLow:%08x "
+		    "maskHigh:%08x",
+		    ue_l, ue_h, hba->sli.sli4.ue_mask_lo,
+		    hba->sli.sli4.ue_mask_hi);
 
 		EMLXS_STATE_CHANGE(hba, FC_ERROR);
 
@@ -6924,21 +6929,6 @@
 		emlxs_thread_spawn(hba, emlxs_shutdown_thread, NULL, NULL);
 	}
 
-#ifdef FMA_SUPPORT
-	/* The PCI(e) driver generates PCI error when PCI read returns */
-	/* 0xFFFFFFFF value. Since PCICFG_UE_STATUS_ONLINE0 and */
-	/* PCICFG_UE_STATUS_ONLINE1 registers return 0xFFFFFFFF to */
-	/* indicate that no internal component has an unrecoverable */
-	/* error on HBA, no access handle check and just call below */
-	/* function to clear the access handle error here. */
-
-	/* Some S10 versions do not define the ddi_fm_acc_err_clear function */
-	if ((void *)&ddi_fm_acc_err_clear != NULL) {
-		(void) ddi_fm_acc_err_clear(hba->pci_acc_handle,
-		    DDI_FME_VERSION);
-	}
-#endif  /* FMA_SUPPORT */
-
 } /* emlxs_sli4_poll_erratt() */
 
 int
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_solaris.c	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_solaris.c	Thu Dec 03 10:09:44 2009 -0800
@@ -1412,6 +1412,44 @@
 } /* emlxs_port_init() */
 
 
+void
+emlxs_disable_pcie_ce_err(emlxs_hba_t *hba)
+{
+#define	NXT_PTR_OFF		PCI_BYTE
+#define	PCIE_DEVCTL_OFF		0x8
+#define	PCIE_CAP_ID		0x10
+
+	uint8_t	cap_ptr;
+	uint8_t	cap_id;
+	uint16_t  tmp16;
+
+	cap_ptr = ddi_get8(hba->pci_acc_handle,
+	    (uint8_t *)(hba->pci_addr + PCI_CAP_POINTER));
+
+	while (cap_ptr) {
+		cap_id = ddi_get8(hba->pci_acc_handle,
+		    (uint8_t *)(hba->pci_addr + cap_ptr));
+
+		if (cap_id == PCIE_CAP_ID) {
+			break;
+		}
+		cap_ptr = ddi_get8(hba->pci_acc_handle,
+		    (uint8_t *)(hba->pci_addr + cap_ptr + NXT_PTR_OFF));
+	}
+
+	/* PCI Express Capability Register Set */
+	/* Turn off the Correctable Error Reporting */
+	/* (the Device Control Register, bit 0). */
+
+	if (cap_id == PCIE_CAP_ID) {
+		tmp16 = ddi_get16(hba->pci_acc_handle,
+		    (uint16_t *)(hba->pci_addr + cap_ptr + PCIE_DEVCTL_OFF));
+		tmp16 &= ~1;
+		(void) ddi_put16(hba->pci_acc_handle,
+		    (uint16_t *)(hba->pci_addr + cap_ptr + PCIE_DEVCTL_OFF),
+		    tmp16);
+	}
+}
 
 /*
  * emlxs_bind_port
@@ -1632,6 +1670,12 @@
 
 	}
 
+	/* PCIE Correctable Error Reporting workaround */
+	if ((hba->model_info.chip == EMLXS_BE_CHIP) &&
+	    (bind_info->port_num == 0)) {
+		emlxs_disable_pcie_ce_err(hba);
+	}
+
 	/* Save initial state */
 	port->ulp_statec = port_info->pi_port_state;
 
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_config.h	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_config.h	Thu Dec 03 10:09:44 2009 -0800
@@ -363,7 +363,7 @@
 #ifdef FMA_SUPPORT
 	/* CFG_FM_CAPS */
 	{"fm-capable",
-		0, 0xF, 0xF, 0,
+		0, 0xF, 0xB, 0,
 		PARM_HEX | PARM_HIDDEN,
 	"Sets FMA capabilities. [bit 3:errcb, 2:dmachk, 1:accchk, 0:ereport]"},
 #endif	/* FMA_SUPPORT */
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_dfclib.h	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_dfclib.h	Thu Dec 03 10:09:44 2009 -0800
@@ -196,6 +196,7 @@
 #define	MBX_READ_LA64		0x95
 #define	MBX_FLASH_WR_ULA	0x98
 #define	MBX_SET_DEBUG		0x99
+#define	MBX_SLI_CONFIG		0x9B
 #define	MBX_LOAD_EXP_ROM	0x9C
 #define	MBX_REQUEST_FEATURES	0x9D
 #define	MBX_RESUME_RPI		0x9E
@@ -379,6 +380,131 @@
 } update_cfg_var_t;
 
 
+
+typedef struct
+{
+	union {
+		struct {
+#ifdef EMLXS_BIG_ENDIAN
+			uint8_t domain;
+			uint8_t port_number;
+			uint8_t subsystem;
+			uint8_t opcode;
+#else
+			uint8_t opcode;
+			uint8_t subsystem;
+			uint8_t port_number;
+			uint8_t domain;
+#endif
+			uint32_t timeout;
+			uint32_t request_length;
+			uint32_t rsvd0;
+		}req;
+
+		struct {
+#ifdef EMLXS_BIG_ENDIAN
+			/* dw 0 */
+			uint8_t domain;
+			uint8_t rsvd0;
+			uint8_t subsystem;
+			uint8_t opcode;
+
+			/* dw 1 */
+			uint16_t rsvd1;
+			uint8_t additional_status;
+			uint8_t status;
+#else
+			/* dw 0 */
+			uint8_t opcode;
+			uint8_t subsystem;
+			uint8_t rsvd0;
+			uint8_t domain;
+
+			/* dw 1 */
+			uint8_t status;
+			uint8_t additional_status;
+			uint16_t rsvd1;
+#endif
+
+			uint32_t rsp_length;
+			uint32_t actual_rsp_length;
+		}rsp;
+		uint32_t dw[4];
+	}u0;
+} common_hdr_t;
+
+typedef struct get_oem_attrs
+{
+	common_hdr_t hdr;
+	union {
+		struct {
+			uint32_t rsvd0;
+		}req;
+
+		struct {
+			uint8_t emulex_serial_number[12];
+			uint8_t oem_serial_number[24];
+			uint32_t oem_personality_mgmt_word;
+#ifdef EMLXS_BIG_ENDIAN
+			uint8_t rsvd[3];
+			uint8_t oem_current_personality;
+#else
+			uint8_t oem_current_personality;
+			uint8_t rsvd[3];
+#endif
+
+		}rsp;
+	}params;
+
+} get_oem_attrs_t;
+
+
+typedef struct read_write_flashrom {
+	common_hdr_t hdr;
+	uint32_t	flash_op_code;
+	uint32_t	flash_op_type;
+	uint32_t	data_buffer_size;
+	uint32_t	data_offset;
+	uint8_t		data_buffer[4];
+} read_write_flashrom_t;
+
+
+typedef struct
+{
+#ifdef EMLXS_BIG_ENDIAN
+	uint32_t	special:8;		/* word 1 */
+	uint32_t	reserved2:16;		/* word 1 */
+	uint32_t	sge_cnt:5;		/* word 1 */
+	uint32_t	reserved1:2;		/* word 1 */
+	uint32_t	embedded:1;		/* word 1 */
+#endif
+#ifdef EMLXS_LITTLE_ENDIAN
+	uint32_t	embedded:1;		/* word 1 */
+	uint32_t	reserved1:2;		/* word 1 */
+	uint32_t	sge_cnt:5;		/* word 1 */
+	uint32_t	reserved2:16;		/* word 1 */
+	uint32_t	special:8;		/* word 1 */
+#endif
+	uint32_t	payload_length;		/* word 2 */
+	uint32_t	tag_low;		/* word 3 */
+	uint32_t	tag_hi;			/* word 4 */
+	uint32_t	reserved3;		/* word 5 */
+
+} be_req_header_t;
+
+typedef struct
+{
+	be_req_header_t	be;
+
+	union
+	{
+		get_oem_attrs_t		varOemAttrs;
+		read_write_flashrom_t	varFlashRom;
+	} un;
+
+} sli_config_var_t;
+
+
 typedef struct read_cfg_var
 {
 #ifdef EMLXS_BIG_ENDIAN
@@ -573,10 +699,13 @@
 		uint32_t		varWords[63];
 		dump4_var_t		varDmp;
 		update_cfg_var_t	varUpdateCfg;
+		sli_config_var_t	varSLIConfig;
 	} un;
 } dfc_mailbox4_t;
 
 
+
+
 /* Config Region 23 Records */
 
 typedef struct tlv_fcoe {
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_extern.h	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_extern.h	Thu Dec 03 10:09:44 2009 -0800
@@ -682,7 +682,10 @@
 					CHANNEL *cp);
 extern void			emlxs_abort_ct_exchange(emlxs_hba_t *hba,
 					emlxs_port_t *port, uint32_t rxid);
-
+extern void			emlxs_abort_els_exchange(emlxs_hba_t *hba,
+					emlxs_port_t *port, uint32_t rxid);
+extern void			emlxs_abort_fct_exchange(emlxs_hba_t *hba,
+					emlxs_port_t *port, uint32_t rxid);
 extern emlxs_buf_t		*emlxs_chipq_get(CHANNEL *cp, uint16_t iotag);
 extern void			emlxs_chipq_put(CHANNEL *cp, emlxs_buf_t *sbp);
 extern uint32_t			emlxs_chipq_node_flush(emlxs_port_t *port,
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fc.h	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fc.h	Thu Dec 03 10:09:44 2009 -0800
@@ -1658,6 +1658,8 @@
 
 	RXQ_DESC_t	rxq[EMLXS_MAX_RXQS];
 
+	uint32_t	ue_mask_lo;
+	uint32_t	ue_mask_hi;
 } emlxs_sli4_t;
 
 
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fcio.h	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fcio.h	Thu Dec 03 10:09:44 2009 -0800
@@ -91,7 +91,9 @@
 								/* offline */
 #define	EMLXS_NO_BOOT_CODE		(EMLXS_ERRNO_START + 5)	/* No boot */
 								/* code image */
-#define	EMLXS_ERRNO_END			(EMLXS_ERRNO_START + 5)
+#define	EMLXS_OP_NOT_SUP		(EMLXS_ERRNO_START + 6)	/* Operation */
+								/* not supp */
+#define	EMLXS_ERRNO_END			(EMLXS_ERRNO_START + 6)
 
 
 typedef struct emlxs_parm
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_hw.h	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_hw.h	Thu Dec 03 10:09:44 2009 -0800
@@ -690,6 +690,8 @@
 /* PCI Config Register offsets */
 #define	PCICFG_UE_STATUS_LO_OFFSET	0xA0	/* Error Indication - low */
 #define	PCICFG_UE_STATUS_HI_OFFSET	0xA4	/* Error Indication - high */
+#define	PCICFG_UE_MASK_LO_OFFSET	0xA8	/* Error mask - low */
+#define	PCICFG_UE_MASK_HI_OFFSET	0xAC	/* Error mask - high */
 #define	PCICFG_UE_STATUS_ONLINE1	0xB0	/* Error status1 */
 #define	PCICFG_UE_STATUS_ONLINE2	0xB4	/* Error status2 */
 
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_version.h	Thu Dec 03 12:01:36 2009 -0500
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_version.h	Thu Dec 03 10:09:44 2009 -0800
@@ -31,10 +31,10 @@
 extern "C" {
 #endif
 
-#define	EMLXS_VERSION		"2.50i"
+#define	EMLXS_VERSION		"2.50k"
 #define	EMLXS_DATE_MINUTE	"30"	/* 00-59 */
-#define	EMLXS_DATE_HOUR		"12"	/* 00-23 */
-#define	EMLXS_DATE_DAY		"10"	/* 00-31 */
+#define	EMLXS_DATE_HOUR		"11"	/* 00-23 */
+#define	EMLXS_DATE_DAY		"25"	/* 00-31 */
 #define	EMLXS_DATE_MONTH	"11"	/* 01-12 */
 #define	EMLXS_DATE_YEAR		"2009"	/* YYYY  */