--- old/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c	Fri Feb 28 10:31:35 2014
+++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c	Fri Feb 28 10:31:35 2014
@@ -2021,6 +2021,7 @@
 {
 	ddi_dma_attr_t	task_dma_attrs;
 
+	mpt->m_hshk_dma_size = 0;
 	task_dma_attrs = mpt->m_msg_dma_attr;
 	task_dma_attrs.dma_attr_sgllen = 1;
 	task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size);
@@ -2039,6 +2040,8 @@
 static void
 mptsas_free_handshake_msg(mptsas_t *mpt)
 {
+	if (mpt->m_hshk_dma_size == 0)
+		return;
 	mptsas_dma_addr_destroy(&mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl);
 	mpt->m_hshk_dma_size = 0;
 }
@@ -15444,7 +15447,6 @@
 
 	if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP,
 	    NULL, dma_hdp) != DDI_SUCCESS) {
-		dma_hdp = NULL;
 		return (FALSE);
 	}
 
@@ -15452,7 +15454,6 @@
 	    DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len,
 	    acc_hdp) != DDI_SUCCESS) {
 		ddi_dma_free_handle(dma_hdp);
-		dma_hdp = NULL;
 		return (FALSE);
 	}
 
@@ -15461,7 +15462,6 @@
 	    cookiep, &ncookie) != DDI_DMA_MAPPED) {
 		(void) ddi_dma_mem_free(acc_hdp);
 		ddi_dma_free_handle(dma_hdp);
-		dma_hdp = NULL;
 		return (FALSE);
 	}
 
@@ -15477,5 +15477,4 @@
 	(void) ddi_dma_unbind_handle(*dma_hdp);
 	(void) ddi_dma_mem_free(acc_hdp);
 	ddi_dma_free_handle(dma_hdp);
-	dma_hdp = NULL;
 }
--- old/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c	Fri Feb 28 10:31:36 2014
+++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c	Fri Feb 28 10:31:36 2014
@@ -309,6 +309,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));
@@ -465,8 +466,12 @@
 	if (mptsas_dma_addr_create(mpt, attrs,
 	    &cmd->cmd_dmahandle, &accessp, &page_memp,
 	    len, &cookie) == FALSE) {
+		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);
 
@@ -584,7 +589,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);
@@ -1857,6 +1863,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 +1890,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 +1904,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:
@@ -2130,8 +2141,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 +2172,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 +2193,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,8 +2230,12 @@
 	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;
 
@@ -2303,8 +2324,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 +2548,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 +2569,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 +2606,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;
 
@@ -2673,8 +2705,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);
