--- /dev/null	Thu Dec 10 09:27:28 2015
+++ new/usr/src/uts/common/io/i40e/i40e_osdep.c	Thu Dec 10 09:27:28 2015
@@ -0,0 +1,292 @@
+/******************************************************************************
+
+  Copyright (c) 2013-2014, Intel Corporation 
+  All rights reserved.
+  
+  Redistribution and use in source and binary forms, with or without 
+  modification, are permitted provided that the following conditions are met:
+  
+   1. Redistributions of source code must retain the above copyright notice, 
+      this list of conditions and the following disclaimer.
+  
+   2. Redistributions in binary form must reproduce the above copyright 
+      notice, this list of conditions and the following disclaimer in the 
+      documentation and/or other materials provided with the distribution.
+  
+   3. Neither the name of the Intel Corporation nor the names of its 
+      contributors may be used to endorse or promote products derived from 
+      this software without specific prior written permission.
+  
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+/*$FreeBSD: head/sys/dev/ixl/i40e_osdep.c 283119 2015-05-19 18:35:18Z jhb $*/
+
+/********************************************************************
+ * Manage DMA'able memory.
+ *******************************************************************/
+
+#include "i40e_sw.h"
+#include "i40e_type.h"
+#include "i40e_alloc.h"
+#include "i40e_osdep.h"
+
+/* NOTE:  No sparc to test on, but I'm drawing inspiration from ixgbe here. */
+#ifdef __sparc
+#define	I40E_DMA_ALIGNMENT	0x0000000000002000ull
+#else
+#define	I40E_DMA_ALIGNMENT	0x0000000000001000ull
+#endif
+
+/*
+ * DMA attributes for rx buffers.
+ * Needs to be viewable for i40e_set_fma_flags().
+ */
+ddi_dma_attr_t i40e_buf_dma_attr = {
+	DMA_ATTR_V0,			/* version number */
+	0x0000000000000000ull,		/* low address */
+	0xFFFFFFFFFFFFFFFFull,		/* high address */
+	0x00000000FFFFFFFFull,		/* dma counter max */
+	I40E_DMA_ALIGNMENT,		/* alignment */
+	0x00000FFF,			/* burst sizes */
+	0x00000001,			/* minimum transfer size */
+	0x00000000FFFFFFFFull,		/* maximum transfer size */
+	0xFFFFFFFFFFFFFFFFull,		/* maximum segment size	 */
+	1,				/* scatter/gather list length */
+	0x00000001,			/* granularity */
+	DDI_DMA_FLAGERR			/* DMA flags */
+};
+
+/*
+ * DMA access attributes for buffers.
+ */
+static ddi_device_acc_attr_t i40e_buf_acc_attr = {
+	DDI_DEVICE_ATTR_V0,
+	DDI_NEVERSWAP_ACC,
+	DDI_STRICTORDER_ACC
+};
+
+i40e_status
+i40e_allocate_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem, u32 size)
+{
+	/* XXX KEBE SAYS -- should we do this? Or instead use a magazine? */
+	/*
+	 * Also, what about prioritization? Use KM_SLEEP? Or instead use
+	 * KM_NOSLEEP | KM_NORMALPRI ?
+	 */
+	mem->va = kmem_alloc(size, KM_SLEEP);
+	mem->size = size;
+	return (I40E_SUCCESS);
+}
+
+i40e_status
+i40e_free_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem)
+{
+	if (mem->va != NULL)
+		kmem_free(mem->va, mem->size);
+	return (I40E_SUCCESS);
+}
+
+i40e_status
+i40e_allocate_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem,
+    enum i40e_memory_type type, u64 size, u32 alignment)
+{
+	int rc;
+	i40e_t *i40e = OS_DEP(hw)->i40e;
+	dev_info_t *dip = i40e->i40e_dip;
+	size_t len;
+	ddi_dma_cookie_t cookie;
+	uint_t cookie_num;
+
+	rc = ddi_dma_alloc_handle(dip, &i40e_buf_dma_attr, DDI_DMA_DONTWAIT,
+	    NULL, &mem->dma_handle);
+	if (rc != DDI_SUCCESS) {
+		mem->dma_handle = NULL;
+		i40e_error(i40e, "ddi_dma_alloc_handle() failed: %d", rc);
+		/* Likely DDI_DMA_NORESOURCES, so return such... */
+		return (I40E_ERR_NO_MEMORY);
+	}
+
+	rc = ddi_dma_mem_alloc(mem->dma_handle, size, &i40e_buf_acc_attr,
+	    DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, NULL, (caddr_t *)&mem->va,
+	    &len, &mem->acc_handle);
+	if (rc != DDI_SUCCESS) {
+		mem->acc_handle = NULL;
+		mem->va = NULL;
+		if (mem->dma_handle != NULL) {
+			ddi_dma_free_handle(&mem->dma_handle);
+			mem->dma_handle = NULL;
+		}
+		i40e_error(i40e, "ddi_dma_mem_alloc() failed: %d", rc);
+		/* rc is only DDI_FAILURE, so again, return NO_MEMORY. */
+		return (I40E_ERR_NO_MEMORY);
+	}
+
+	rc = ddi_dma_addr_bind_handle(mem->dma_handle, NULL, mem->va, len,
+	    DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, NULL,
+	    &cookie, &cookie_num);
+	if (rc != DDI_DMA_MAPPED) {
+		mem->pa = NULL;
+		if (mem->acc_handle == NULL) {
+			ddi_dma_mem_free(&mem->acc_handle);
+			mem->acc_handle = NULL;
+			mem->va = NULL;
+		}
+		if (mem->dma_handle != NULL) {
+			ddi_dma_free_handle(&mem->dma_handle);
+			mem->dma_handle = NULL;
+		}
+		i40e_error(i40e, "ddi_dma_addr_bind_handle() failed: %d", rc);
+		/* Multiple return code here demand multiple returns. */
+		switch (rc) {
+		case DDI_DMA_INUSE:
+			return (I40E_ERR_NOT_READY);
+		case DDI_DMA_TOOBIG:
+			return (I40E_ERR_INVALID_SIZE);
+		case DDI_DMA_NOMAPPING:
+		case DDI_DMA_NORESOURCES:
+		default:
+			return (I40E_ERR_NO_MEMORY);
+		}
+		/* NOTREACHED */
+	}
+
+	ASSERT(cookie_num == 1);	/* From ixgbe.. why?!? */
+	mem->pa = cookie.dmac_laddress;
+	mem->size = len;
+	/* XXX KEBE SAYS ixgbe's object has a "len" -- why?!? */
+
+	return (I40E_SUCCESS);
+}
+
+i40e_status
+i40e_free_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem)
+{
+	if (mem->dma_handle != NULL) {
+		/* XXX KEBE ASKS What should I return if unbind fails? */
+		if (ddi_dma_unbind_handle(mem->dma_handle) != DDI_SUCCESS)
+			return (I40E_ERR_RESET_FAILED);
+		mem->pa = NULL;
+	} else {
+		return (I40E_SUCCESS);
+	}
+
+	if (mem->acc_handle != NULL) {
+		ddi_dma_mem_free(&mem->acc_handle);
+		mem->acc_handle = NULL;
+		mem->va = NULL;
+	}
+
+	if (mem->dma_handle != NULL) {
+		ddi_dma_free_handle(&mem->dma_handle);
+		mem->dma_handle = NULL;
+	}
+
+	mem->size = 0;
+	/* XXX KEBE SAYS see i40e_allocate_dma_mem() for question as to why? */
+	/* mem->len = 0; */
+
+	return (I40E_SUCCESS);
+}
+
+void
+i40e_init_spinlock(struct i40e_spinlock *lock, struct i40e_hw *hw)
+{
+	i40e_t *i40e = OS_DEP(hw)->i40e;
+	void *arg;
+
+	/*
+	 * I MAY very well not have i40e_intr_pri *set* before this gets
+	 * called.  In that case, just set priority = 0, and assume that the
+	 * caller (i40e setup code) will call functions that
+	 * dispose-then-initialize spinlocks.  We also assume that the caller
+	 * is in attach context, and will HAVE INTERRUPTS ALLOCATED IN
+	 * ATTACH CONTEXT when disposing-then-initializing spinlocks.
+	 *
+	 * Currently, the only caller of this is via i40e_common_code_init(),
+	 * in particular the i40e_init_adminq() common-code-call.
+	 */
+	if (i40e->i40e_intr_handles == NULL) {
+		/* Allocate priority 0 for now. */
+		arg = DDI_INTR_PRI(0);
+	} else {
+		/* Aha!  We have enough to allocate proper MUTEX_DRIVER. */
+		arg = DDI_INTR_PRI(i40e->i40e_intr_pri);
+	}
+	mutex_init(&lock->mutex, NULL, MUTEX_DRIVER, arg);
+}
+
+void
+i40e_acquire_spinlock(struct i40e_spinlock *lock)
+{
+	mutex_enter(&lock->mutex);
+}
+
+void
+i40e_release_spinlock(struct i40e_spinlock *lock)
+{
+	mutex_exit(&lock->mutex);
+}
+
+void
+i40e_destroy_spinlock(struct i40e_spinlock *lock)
+{
+	mutex_destroy(&lock->mutex);
+}
+
+boolean_t
+i40e_set_hw_bus_info(struct i40e_hw *hw)
+{
+	uint8_t pcie_id = PCI_CAP_ID_PCI_E;
+	uint16_t pcie_cap, value;
+	int status;
+
+	/* locate the pci-e capability block */
+	status = pci_lcap_locate((OS_DEP(hw))->cfg_handle, pcie_id, &pcie_cap);
+	if (status != DDI_SUCCESS) {
+		i40e_error(OS_DEP(hw)->i40e, "pci_lcap_locate() failed %d",
+		    status);
+		return (B_FALSE);
+	}
+
+	/*
+	 * Get the low 16 bits.  PCIe is little-endian so just do a get16()
+	 * on things.
+	 */
+	value = pci_config_get16(OS_DEP(hw)->cfg_handle,
+	    (pcie_cap + PCIE_LINKSTS));
+
+	i40e_set_pci_config_data(hw, value);
+
+	return (B_TRUE);
+}
+
+/*
+ * RENAMED from i40e_debug_d because the SunPRO compilers don't support
+ * ##__VA_ARGS__ to solve the trailing comma problem.
+*/
+void i40e_debug(void *hw, u32 mask, char *fmt, ...)
+{
+        char buf[512];
+        va_list args;
+
+        if (!(mask & ((struct i40e_hw *)hw)->debug_mask))
+                return;
+
+	va_start(args, fmt);
+        vsnprintf(buf, sizeof(buf), fmt, args);
+	va_end(args);
+
+        /* the debug string is already formatted with a newline */
+        printf("%s", buf);
+}
