--- old/usr/src/uts/common/io/scsi/adapters/mpt_sas3/mptsas3_impl.c	2014-06-12 17:42:16.878312556 +0100
+++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas3/mptsas3_impl.c	2014-06-12 17:42:16.884650279 +0100
@@ -22,6 +22,8 @@
 /*
  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
+ * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
  */
 
 /*
@@ -68,20 +70,20 @@
 #include <sys/pci.h>
 
 #pragma pack(1)
-#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
-#include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
-#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
-#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
-#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
-#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
-#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
+#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_type.h>
+#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2.h>
+#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_cnfg.h>
+#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_init.h>
+#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_ioc.h>
+#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_sas.h>
+#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_tool.h>
 #pragma pack()
 
 /*
  * private header files.
  */
-#include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
-#include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
+#include <sys/scsi/adapters/mpt_sas3/mptsas3_var.h>
+#include <sys/scsi/adapters/mpt_sas3/mptsas3_smhba.h>
 
 /*
  * FMA header files.
@@ -90,6 +92,7 @@
 
 #if defined(MPTSAS_DEBUG)
 extern uint32_t mptsas_debug_flags;
+extern uint32_t mptsas_dbglog_imask;
 #endif
 
 /*
@@ -205,7 +208,8 @@
 	struct scsi_pkt		*pkt = cmd->cmd_pkt;
 	mptsas_config_request_t	*config = pkt->pkt_ha_private;
 	uint8_t			direction;
-	uint32_t		length, flagslength, request_desc_low;
+	uint32_t		length, flagslength;
+	uint64_t		request_desc;
 
 	ASSERT(mutex_owned(&mpt->m_mutex));
 
@@ -259,7 +263,7 @@
 			direction = MPI2_SGE_FLAGS_HOST_TO_IOC;
 		}
 		ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low,
-		    (uint32_t)cmd->cmd_dma_addr);
+		    (uint32_t)(cmd->cmd_dma_addr&0xfffffffful));
 		ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High,
 		    (uint32_t)(cmd->cmd_dma_addr >> 32));
 	}
@@ -279,10 +283,10 @@
 
 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
 	    DDI_DMA_SYNC_FORDEV);
-	request_desc_low = (cmd->cmd_slot << 16) +
+	request_desc = (cmd->cmd_slot << 16) +
 	    MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cmd->cmd_rfm = NULL;
-	MPTSAS_START_CMD(mpt, request_desc_low, 0);
+	MPTSAS_START_CMD(mpt, request_desc);
 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
 	    DDI_SUCCESS) ||
 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
@@ -309,6 +313,7 @@
 	uint16_t		iocstatus = 0;
 	uint32_t		iocloginfo;
 	caddr_t			page_memp;
+	boolean_t		free_dma = B_FALSE;
 
 	va_start(ap, callback);
 	ASSERT(mutex_owned(&mpt->m_mutex));
@@ -391,7 +396,7 @@
 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
 		    DDI_DMA_SYNC_FORCPU);
 		reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm
-		    - mpt->m_reply_frame_dma_addr));
+		    - (mpt->m_reply_frame_dma_addr&0xfffffffful)));
 		config.page_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
 		    &reply->Header.PageType);
 		config.page_number = ddi_get8(mpt->m_acc_reply_frame_hdl,
@@ -465,8 +470,14 @@
 	if (mptsas_dma_addr_create(mpt, attrs,
 	    &cmd->cmd_dmahandle, &accessp, &page_memp,
 	    len, &cookie) == FALSE) {
+		mptsas_log(mpt, CE_WARN,
+		    "mptsas_dma_addr_create(len=0x%x) failed", (int)len);
+		rval = DDI_FAILURE;
 		goto page_done;
 	}
+	/* NOW we can safely call mptsas_dma_addr_destroy(). */
+	free_dma = B_TRUE;
+
 	cmd->cmd_dma_addr = cookie.dmac_laddress;
 	bzero(page_memp, len);
 
@@ -530,7 +541,7 @@
 		(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
 		    DDI_DMA_SYNC_FORCPU);
 		reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm
-		    - mpt->m_reply_frame_dma_addr));
+		    - (mpt->m_reply_frame_dma_addr&0xfffffffful)));
 		iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
 		    &reply->IOCStatus);
 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
@@ -584,7 +595,8 @@
 		    mpt->m_free_index);
 	}
 
-	mptsas_dma_addr_destroy(&cmd->cmd_dmahandle, &accessp);
+	if (free_dma)
+		mptsas_dma_addr_destroy(&cmd->cmd_dmahandle, &accessp);
 
 	if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
 		mptsas_remove_cmd(mpt, cmd);
@@ -606,7 +618,7 @@
 int
 mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action, uint8_t pagetype,
 	uint32_t pageaddress, uint8_t pagenumber, uint8_t pageversion,
-	uint8_t pagelength, uint32_t SGEflagslength, uint32_t SGEaddress32)
+	uint8_t pagelength, uint32_t SGEflagslength, uint64_t SGEaddress)
 {
 	pMpi2ConfigRequest_t	config;
 	int			send_numbytes;
@@ -623,7 +635,11 @@
 	ddi_put32(mpt->m_hshk_acc_hdl,
 	    &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength);
 	ddi_put32(mpt->m_hshk_acc_hdl,
-	    &config->PageBufferSGE.MpiSimple.u.Address32, SGEaddress32);
+	    &config->PageBufferSGE.MpiSimple.u.Address64.Low,
+	    SGEaddress&0xfffffffful);
+	ddi_put32(mpt->m_hshk_acc_hdl,
+	    &config->PageBufferSGE.MpiSimple.u.Address64.High,
+	    SGEaddress >> 32);
 	send_numbytes = sizeof (MPI2_CONFIG_REQUEST);
 
 	/*
@@ -640,7 +656,7 @@
 mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action,
 	uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber,
 	uint8_t pageversion, uint16_t extpagelength,
-	uint32_t SGEflagslength, uint32_t SGEaddress32)
+	uint32_t SGEflagslength, uint64_t SGEaddress)
 {
 	pMpi2ConfigRequest_t	config;
 	int			send_numbytes;
@@ -659,7 +675,11 @@
 	ddi_put32(mpt->m_hshk_acc_hdl,
 	    &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength);
 	ddi_put32(mpt->m_hshk_acc_hdl,
-	    &config->PageBufferSGE.MpiSimple.u.Address32, SGEaddress32);
+	    &config->PageBufferSGE.MpiSimple.u.Address64.Low,
+	    SGEaddress&0xfffffffful);
+	ddi_put32(mpt->m_hshk_acc_hdl,
+	    &config->PageBufferSGE.MpiSimple.u.Address64.High,
+	    SGEaddress >> 32);
 	send_numbytes = sizeof (MPI2_CONFIG_REQUEST);
 
 	/*
@@ -1087,7 +1107,8 @@
 	mptsas_cmd_t				*cmd;
 	struct scsi_pkt				*pkt;
 	mptsas_slots_t				*slots = mpt->m_active;
-	uint32_t				request_desc_low, i;
+	uint32_t				i;
+	uint64_t				request_desc;
 	pMPI2DefaultReply_t			reply_msg;
 
 	/*
@@ -1143,9 +1164,9 @@
 	 */
 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
 	    DDI_DMA_SYNC_FORDEV);
-	request_desc_low = (cmd->cmd_slot << 16) +
+	request_desc = (cmd->cmd_slot << 16) +
 	    MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
-	MPTSAS_START_CMD(mpt, request_desc_low, 0);
+	MPTSAS_START_CMD(mpt, request_desc);
 	rval = mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
 
 	if (pkt->pkt_reason == CMD_INCOMPLETE)
@@ -1161,7 +1182,7 @@
 		    DDI_DMA_SYNC_FORCPU);
 		reply_msg = (pMPI2DefaultReply_t)
 		    (mpt->m_reply_frame + (cmd->cmd_rfm -
-		    mpt->m_reply_frame_dma_addr));
+		    (mpt->m_reply_frame_dma_addr&0xfffffffful)));
 		if (reply_size > sizeof (MPI2_SCSI_TASK_MANAGE_REPLY)) {
 			reply_size = sizeof (MPI2_SCSI_TASK_MANAGE_REPLY);
 		}
@@ -1199,6 +1220,83 @@
 	return (rval);
 }
 
+/*
+ * Complete firmware download frame for v2.0 cards.
+ */
+static void
+mptsas_uflash2(pMpi2FWDownloadRequest fwdownload,
+    ddi_acc_handle_t acc_hdl, uint32_t size, uint8_t type,
+    ddi_dma_cookie_t flsh_cookie)
+{
+	pMpi2FWDownloadTCSGE_t	tcsge;
+	pMpi2SGESimple64_t	sge;
+	uint32_t		flagslength;
+
+	ddi_put8(acc_hdl, &fwdownload->Function,
+	    MPI2_FUNCTION_FW_DOWNLOAD);
+	ddi_put8(acc_hdl, &fwdownload->ImageType, type);
+	ddi_put8(acc_hdl, &fwdownload->MsgFlags,
+	    MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT);
+	ddi_put32(acc_hdl, &fwdownload->TotalImageSize, size);
+
+	tcsge = (pMpi2FWDownloadTCSGE_t)&fwdownload->SGL;
+	ddi_put8(acc_hdl, &tcsge->ContextSize, 0);
+	ddi_put8(acc_hdl, &tcsge->DetailsLength, 12);
+	ddi_put8(acc_hdl, &tcsge->Flags, 0);
+	ddi_put32(acc_hdl, &tcsge->ImageOffset, 0);
+	ddi_put32(acc_hdl, &tcsge->ImageSize, size);
+
+	sge = (pMpi2SGESimple64_t)(tcsge + 1);
+	flagslength = size;
+	flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
+	    MPI2_SGE_FLAGS_END_OF_BUFFER |
+	    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
+	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
+	    MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
+	    MPI2_SGE_FLAGS_HOST_TO_IOC |
+	    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
+	ddi_put32(acc_hdl, &sge->FlagsLength, flagslength);
+	ddi_put32(acc_hdl, &sge->Address.Low,
+	    flsh_cookie.dmac_address);
+	ddi_put32(acc_hdl, &sge->Address.High,
+	    (uint32_t)(flsh_cookie.dmac_laddress >> 32));
+}
+
+/*
+ * Complete firmware download frame for v2.5 cards.
+ */
+static void
+mptsas_uflash25(pMpi25FWDownloadRequest fwdownload,
+    ddi_acc_handle_t acc_hdl, uint32_t size, uint8_t type,
+    ddi_dma_cookie_t flsh_cookie)
+{
+	pMpi2IeeeSgeSimple64_t	sge;
+	uint8_t			flags;
+
+	ddi_put8(acc_hdl, &fwdownload->Function,
+	    MPI2_FUNCTION_FW_DOWNLOAD);
+	ddi_put8(acc_hdl, &fwdownload->ImageType, type);
+	ddi_put8(acc_hdl, &fwdownload->MsgFlags,
+	    MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT);
+	ddi_put32(acc_hdl, &fwdownload->TotalImageSize, size);
+
+	ddi_put32(acc_hdl, &fwdownload->ImageOffset, 0);
+	ddi_put32(acc_hdl, &fwdownload->ImageSize, size);
+
+	sge = (pMpi2IeeeSgeSimple64_t)&fwdownload->SGL;
+	flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
+	    MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR |
+	    MPI25_IEEE_SGE_FLAGS_END_OF_LIST;
+	ddi_put8(acc_hdl, &sge->Flags, flags);
+	ddi_put32(acc_hdl, &sge->Length, size);
+	ddi_put32(acc_hdl, &sge->Address.Low,
+	    flsh_cookie.dmac_address);
+	ddi_put32(acc_hdl, &sge->Address.High,
+	    (uint32_t)(flsh_cookie.dmac_laddress >> 32));
+}
+
+static int mptsas_enable_mpi25_flashupdate = 0;
+
 int
 mptsas_update_flash(mptsas_t *mpt, caddr_t ptrbuffer, uint32_t size,
     uint8_t type, int mode)
@@ -1216,15 +1314,24 @@
 	ddi_dma_handle_t	flsh_dma_handle;
 	ddi_acc_handle_t	flsh_accessp;
 	caddr_t			memp, flsh_memp;
-	uint32_t		flagslength;
-	pMpi2FWDownloadRequest	fwdownload;
-	pMpi2FWDownloadTCSGE_t	tcsge;
-	pMpi2SGESimple64_t	sge;
 	mptsas_cmd_t		*cmd;
 	struct scsi_pkt		*pkt;
 	int			i;
 	int			rvalue = 0;
-	uint32_t		request_desc_low;
+	uint64_t		request_desc;
+
+	if (mpt->m_MPI25) {
+		/*
+		 * The code is there but not tested yet.
+		 * User has to know there are risks here.
+		 */
+		mptsas_log(mpt, CE_WARN, "mptsas_update_flash(): "
+		    "Updating firmware through MPI 2.5 has not been "
+		    "tested yet!\n"
+		    "To enable set mptsas_enable_mpi25_flashupdate to 1\n");
+		if (!mptsas_enable_mpi25_flashupdate)
+			return (-1);
+	}
 
 	if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
 		mptsas_log(mpt, CE_WARN, "mptsas_update_flash(): allocation "
@@ -1285,45 +1392,23 @@
 	ASSERT(cmd->cmd_slot != 0);
 	memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot);
 	bzero(memp, mpt->m_req_frame_size);
-	fwdownload = (void *)memp;
-	ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->Function,
-	    MPI2_FUNCTION_FW_DOWNLOAD);
-	ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->ImageType, type);
-	ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->MsgFlags,
-	    MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT);
-	ddi_put32(mpt->m_acc_req_frame_hdl, &fwdownload->TotalImageSize, size);
 
-	tcsge = (pMpi2FWDownloadTCSGE_t)&fwdownload->SGL;
-	ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->ContextSize, 0);
-	ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->DetailsLength, 12);
-	ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->Flags, 0);
-	ddi_put32(mpt->m_acc_req_frame_hdl, &tcsge->ImageOffset, 0);
-	ddi_put32(mpt->m_acc_req_frame_hdl, &tcsge->ImageSize, size);
-
-	sge = (pMpi2SGESimple64_t)(tcsge + 1);
-	flagslength = size;
-	flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
-	    MPI2_SGE_FLAGS_END_OF_BUFFER |
-	    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
-	    MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
-	    MPI2_SGE_FLAGS_HOST_TO_IOC |
-	    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
-	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength);
-	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low,
-	    flsh_cookie.dmac_address);
-	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High,
-	    (uint32_t)(flsh_cookie.dmac_laddress >> 32));
+	if (mpt->m_MPI25)
+		mptsas_uflash25((pMpi25FWDownloadRequest)memp,
+		    mpt->m_acc_req_frame_hdl, size, type, flsh_cookie);
+	else
+		mptsas_uflash2((pMpi2FWDownloadRequest)memp,
+		    mpt->m_acc_req_frame_hdl, size, type, flsh_cookie);
 
 	/*
 	 * Start command
 	 */
 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
 	    DDI_DMA_SYNC_FORDEV);
-	request_desc_low = (cmd->cmd_slot << 16) +
+	request_desc = (cmd->cmd_slot << 16) +
 	    MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cmd->cmd_rfm = NULL;
-	MPTSAS_START_CMD(mpt, request_desc_low, 0);
+	MPTSAS_START_CMD(mpt, request_desc);
 
 	rvalue = 0;
 	(void) cv_reltimedwait(&mpt->m_fw_cv, &mpt->m_mutex,
@@ -1357,7 +1442,7 @@
 	uint64_t		*sas_wwn;
 	uint32_t		*dev_info;
 	uint8_t			*physport, *phynum;
-	uint16_t		*pdevhdl;
+	uint16_t		*pdevhdl, *io_flags;
 	uint32_t		page_address;
 
 	if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) &&
@@ -1391,7 +1476,7 @@
 	pdevhdl = va_arg(ap, uint16_t *);
 	bay_num = va_arg(ap, uint16_t *);
 	enclosure = va_arg(ap, uint16_t *);
-
+	io_flags = va_arg(ap, uint16_t *);
 
 	sasdevpage = (pMpi2SasDevicePage0_t)page_memp;
 
@@ -1408,6 +1493,19 @@
 	*pdevhdl = ddi_get16(accessp, &sasdevpage->ParentDevHandle);
 	*bay_num = ddi_get16(accessp, &sasdevpage->Slot);
 	*enclosure = ddi_get16(accessp, &sasdevpage->EnclosureHandle);
+	*io_flags = ddi_get16(accessp, &sasdevpage->Flags);
+
+	if (*io_flags & MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) {
+		/*
+		 * Leave a messages about FP cabability in the log.
+		 */
+		mptsas_log(mpt, CE_CONT,
+		    "!w%016"PRIx64" FastPath Capable%s", *sas_wwn,
+		    (*io_flags &
+		    MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH)?
+		    " and Enabled":" but Disabled");
+	}
+
 	return (rval);
 }
 
@@ -1419,7 +1517,7 @@
 mptsas_get_sas_device_page0(mptsas_t *mpt, uint32_t page_address,
     uint16_t *dev_handle, uint64_t *sas_wwn, uint32_t *dev_info,
     uint8_t *physport, uint8_t *phynum, uint16_t *pdev_handle,
-    uint16_t *bay_num, uint16_t *enclosure)
+    uint16_t *bay_num, uint16_t *enclosure, uint16_t *io_flags)
 {
 	int rval = DDI_SUCCESS;
 
@@ -1434,7 +1532,7 @@
 	    MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0, page_address,
 	    mptsas_sasdevpage_0_cb, page_address, dev_handle, sas_wwn,
 	    dev_info, physport, phynum, pdev_handle,
-	    bay_num, enclosure);
+	    bay_num, enclosure, io_flags);
 
 	return (rval);
 }
@@ -1857,6 +1955,7 @@
 	uint32_t		reply_size = 256; /* Big enough for any page */
 	uint_t			state;
 	int			rval = DDI_FAILURE;
+	boolean_t		free_recv = B_FALSE, free_page = B_FALSE;
 
 	/*
 	 * Initialize our "state machine".  This is a bit convoluted,
@@ -1883,6 +1982,8 @@
 		    "mptsas_get_sas_io_unit_page_hndshk: recv dma failed");
 		goto cleanup;
 	}
+	/* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */
+	free_recv = B_TRUE;
 
 	page_dma_attrs = mpt->m_msg_dma_attr;
 	page_dma_attrs.dma_attr_sgllen = 1;
@@ -1895,6 +1996,8 @@
 		    "mptsas_get_sas_io_unit_page_hndshk: page dma failed");
 		goto cleanup;
 	}
+	/* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */
+	free_page = B_TRUE;
 
 	/*
 	 * Now we cycle through the state machine.  Here's what happens:
@@ -1917,7 +2020,7 @@
 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
 			    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
-			    MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
+			    MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
 			    MPI2_SGE_FLAGS_IOC_TO_HOST |
 			    MPI2_SGE_FLAGS_END_OF_LIST) <<
 			    MPI2_SGE_FLAGS_SHIFT);
@@ -1933,7 +2036,7 @@
 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
 			    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
-			    MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
+			    MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
 			    MPI2_SGE_FLAGS_IOC_TO_HOST |
 			    MPI2_SGE_FLAGS_END_OF_LIST) <<
 			    MPI2_SGE_FLAGS_SHIFT);
@@ -1977,7 +2080,7 @@
 		    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, page_number,
 		    ddi_get8(recv_accessp, &configreply->Header.PageVersion),
 		    ddi_get16(recv_accessp, &configreply->ExtPageLength),
-		    flags_length, page_cookie.dmac_address)) {
+		    flags_length, page_cookie.dmac_laddress)) {
 			goto cleanup;
 		}
 
@@ -2130,8 +2233,10 @@
 	}
 
 cleanup:
-	mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
-	mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
+	if (free_recv)
+		mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
+	if (free_page)
+		mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
 	if (rval != DDI_SUCCESS) {
 		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
@@ -2159,6 +2264,7 @@
 	uint32_t			flagslength;
 	int				rval = DDI_SUCCESS;
 	uint_t				iocstatus;
+	boolean_t		free_recv = B_FALSE, free_page = B_FALSE;
 
 	MPTSAS_DISABLE_INTR(mpt);
 
@@ -2179,8 +2285,11 @@
 	if (mptsas_dma_addr_create(mpt, recv_dma_attrs,
 	    &recv_dma_handle, &recv_accessp, &recv_memp,
 	    (sizeof (MPI2_CONFIG_REPLY)), NULL) == FALSE) {
+		rval = DDI_FAILURE;
 		goto done;
 	}
+	/* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */
+	free_recv = B_TRUE;
 
 	bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY));
 	configreply = (pMpi2ConfigReply_t)recv_memp;
@@ -2213,10 +2322,17 @@
 	if (mptsas_dma_addr_create(mpt, page_dma_attrs, &page_dma_handle,
 	    &page_accessp, &page_memp, (sizeof (MPI2_CONFIG_PAGE_MAN_5)),
 	    &page_cookie) == FALSE) {
+		rval = DDI_FAILURE;
 		goto done;
 	}
+	/* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */
+	free_page = B_TRUE;
+
 	bzero(page_memp, sizeof (MPI2_CONFIG_PAGE_MAN_5));
 	m5 = (pMpi2ManufacturingPage5_t)page_memp;
+	NDBG20(("mptsas_get_manufacture_page5: paddr 0x%x%08x",
+	    (uint32_t)(page_cookie.dmac_laddress>>32),
+	    (uint32_t)(page_cookie.dmac_laddress&0xfffffffful)));
 
 	/*
 	 * Give reply address to IOC to store config page in and send
@@ -2226,7 +2342,7 @@
 	flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_5);
 	flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
 	    MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
+	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
 	    MPI2_SGE_FLAGS_IOC_TO_HOST |
 	    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
 
@@ -2235,7 +2351,7 @@
 	    MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5,
 	    ddi_get8(recv_accessp, &configreply->Header.PageVersion),
 	    ddi_get8(recv_accessp, &configreply->Header.PageLength),
-	    flagslength, page_cookie.dmac_address)) {
+	    flagslength, page_cookie.dmac_laddress)) {
 		rval = DDI_FAILURE;
 		goto done;
 	}
@@ -2303,8 +2419,10 @@
 	/*
 	 * free up memory
 	 */
-	mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
-	mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
+	if (free_recv)
+		mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
+	if (free_page)
+		mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
 	MPTSAS_ENABLE_INTR(mpt);
 
 	return (rval);
@@ -2525,6 +2643,7 @@
 	int				rval = DDI_SUCCESS;
 	uint_t				iocstatus;
 	uint8_t				i = 0;
+	boolean_t		free_recv = B_FALSE, free_page = B_FALSE;
 
 	MPTSAS_DISABLE_INTR(mpt);
 
@@ -2545,8 +2664,12 @@
 	if (mptsas_dma_addr_create(mpt, recv_dma_attrs, &recv_dma_handle,
 	    &recv_accessp, &recv_memp, (sizeof (MPI2_CONFIG_REPLY)),
 	    NULL) == FALSE) {
+		rval = DDI_FAILURE;
 		goto done;
 	}
+	/* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */
+	free_recv = B_TRUE;
+
 	bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY));
 	configreply = (pMpi2ConfigReply_t)recv_memp;
 	recv_numbytes = sizeof (MPI2_CONFIG_REPLY);
@@ -2578,8 +2701,12 @@
 	if (mptsas_dma_addr_create(mpt, page_dma_attrs, &page_dma_handle,
 	    &page_accessp, &page_memp, (sizeof (MPI2_CONFIG_PAGE_MAN_0)),
 	    &page_cookie) == FALSE) {
+		rval = DDI_FAILURE;
 		goto done;
 	}
+	/* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */
+	free_page = B_TRUE;
+
 	bzero(page_memp, sizeof (MPI2_CONFIG_PAGE_MAN_0));
 	m0 = (pMpi2ManufacturingPage0_t)page_memp;
 
@@ -2591,7 +2718,7 @@
 	flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_0);
 	flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
 	    MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
-	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
+	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
 	    MPI2_SGE_FLAGS_IOC_TO_HOST |
 	    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
 
@@ -2600,7 +2727,7 @@
 	    MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 0,
 	    ddi_get8(recv_accessp, &configreply->Header.PageVersion),
 	    ddi_get8(recv_accessp, &configreply->Header.PageLength),
-	    flagslength, page_cookie.dmac_address)) {
+	    flagslength, page_cookie.dmac_laddress)) {
 		rval = DDI_FAILURE;
 		goto done;
 	}
@@ -2673,8 +2800,10 @@
 	/*
 	 * free up memory
 	 */
-	mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
-	mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
+	if (free_recv)
+		mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
+	if (free_page)
+		mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
 	MPTSAS_ENABLE_INTR(mpt);
 
 	return (rval);
