summaryrefslogtreecommitdiff
path: root/src/VBox/Additions/solaris/Virtio/Virtio-solaris.c
diff options
context:
space:
mode:
authorvboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2010-11-17 20:05:36 +0000
committervboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2010-11-17 20:05:36 +0000
commit38763ced53df3370d1ca450cf374e6c53d3d8ade (patch)
treeedf73c2f4ba1fa1579f4b80c9dce7bb71b8fec3b /src/VBox/Additions/solaris/Virtio/Virtio-solaris.c
parentc74d3b46f79db42e6a7a842aa46bf136755a5eb3 (diff)
downloadVirtualBox-svn-38763ced53df3370d1ca450cf374e6c53d3d8ade.tar.gz
Additions/Solaris/Virtio: export to OSE
git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@34143 cfe28804-0f27-0410-a406-dd0f0b0b656f
Diffstat (limited to 'src/VBox/Additions/solaris/Virtio/Virtio-solaris.c')
-rw-r--r--src/VBox/Additions/solaris/Virtio/Virtio-solaris.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/VBox/Additions/solaris/Virtio/Virtio-solaris.c b/src/VBox/Additions/solaris/Virtio/Virtio-solaris.c
new file mode 100644
index 00000000000..3c80465365f
--- /dev/null
+++ b/src/VBox/Additions/solaris/Virtio/Virtio-solaris.c
@@ -0,0 +1,206 @@
+/* $Id$ */
+/** @file
+ * VirtualBox Guest Additions: Virtio Driver for Solaris.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * Oracle Corporation confidential
+ * All rights reserved
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "Virtio-solaris.h"
+
+#include <iprt/assert.h>
+#include <iprt/mem.h>
+#include <VBox/log.h>
+
+#if defined(DEBUG_ramshankar)
+# undef LogFlowFunc
+# define LogFlowFunc LogRel
+# undef Log
+# define Log LogRel
+# undef LogFlow
+# define LogFlow LogRel
+#endif
+
+/**
+ * Virtio Attach routine that should be called from all Virtio drivers' attach
+ * routines.
+ *
+ * @param pDip The module structure instance.
+ * @param enmCmd Operation type (attach/resume).
+ * @param pDeviceOps Pointer to device ops structure.
+ * @param pHyperOps Pointer to hypervisor ops structure.
+ *
+ * @return Solaris DDI error code. DDI_SUCCESS or DDI_FAILURE.
+ */
+int VirtioAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd, PVIRTIODEVICEOPS pDeviceOps, PVIRTIOHYPEROPS pHyperOps)
+{
+ LogFlowFunc((VIRTIOLOGNAME ":VirtioAttach: pDip=%p enmCmd=%d pDeviceOps=%p pHyperOps=%p\n", pDip, enmCmd, pDeviceOps, pHyperOps));
+
+ AssertReturn(pDip, DDI_EINVAL);
+ AssertReturn(pDeviceOps, DDI_EINVAL);
+ AssertReturn(pHyperOps, DDI_EINVAL);
+
+ if (enmCmd != DDI_ATTACH)
+ {
+ LogRel((VIRTIOLOGNAME ":VirtioAttach: Invalid enmCmd=%#x expected DDI_ATTACH\n", enmCmd));
+ return DDI_FAILURE;
+ }
+
+ int rc = DDI_FAILURE;
+ PVIRTIODEVICE pDevice = RTMemAllocZ(sizeof(VIRTIODEVICE));
+ if (RT_LIKELY(pDevice))
+ {
+ pDevice->pDip = pDip;
+ pDevice->pDeviceOps = pDeviceOps;
+ pDevice->pHyperOps = pHyperOps;
+
+ pDevice->pvDevice = pDevice->pDeviceOps->pfnAlloc(pDevice);
+ if (RT_LIKELY(pDevice->pvDevice))
+ {
+ pDevice->pvHyper = pDevice->pHyperOps->pfnAlloc(pDevice);
+ if (RT_LIKELY(pDevice->pvHyper))
+ {
+ /*
+ * Attach hypervisor interface and obtain features supported by host.
+ */
+ rc = pDevice->pHyperOps->pfnAttach(pDevice);
+ if (rc == DDI_SUCCESS)
+ {
+ pDevice->fHostFeatures = pDevice->pHyperOps->pfnGetFeatures(pDevice);
+ LogFlow((VIRTIOLOGNAME ":VirtioAttach: Host features=%#x\n", pDevice->fHostFeatures));
+
+ /*
+ * Attach the device type interface.
+ */
+ rc = pDevice->pDeviceOps->pfnAttach(pDevice);
+ if (rc == DDI_SUCCESS)
+ {
+ ddi_set_driver_private(pDip, pDevice);
+ return DDI_SUCCESS;
+ }
+ else
+ LogRel((VIRTIOLOGNAME ":VirtioAttach: DeviceOps pfnAttach failed. rc=%d\n", rc));
+
+ pDevice->pHyperOps->pfnDetach(pDevice);
+ }
+ else
+ LogRel((VIRTIOLOGNAME ":VirtioAttach: HyperOps pfnAttach failed. rc=%d\n", rc));
+
+ pDevice->pHyperOps->pfnFree(pDevice);
+ }
+ else
+ LogRel((VIRTIOLOGNAME ":VirtioAttach: HyperOps->pfnAlloc failed!\n"));
+
+ pDevice->pDeviceOps->pfnFree(pDevice);
+ }
+ else
+ LogRel((VIRTIOLOGNAME ":VirtioAttach: DeviceOps->pfnAlloc failed!\n"));
+
+ RTMemFree(pDevice);
+ }
+ else
+ LogRel((VIRTIOLOGNAME ":VirtioAttach: failed to alloc %u bytes for device structure.\n", sizeof(VIRTIODEVICE)));
+
+ return DDI_FAILURE;
+}
+
+
+/**
+ * Virtio Detach routine that should be called from all Virtio drivers' detach
+ * routines.
+ *
+ * @param pDip The module structure instance.
+ * @param enmCmd Operation type (detach/suspend).
+ *
+ * @return Solaris DDI error code. DDI_SUCCESS or DDI_FAILURE.
+ */
+int VirtioDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
+{
+ LogFlowFunc((VIRTIOLOGNAME ":VirtioDetach pDip=%p enmCmd=%d\n", pDip, enmCmd));
+
+ PVIRTIODEVICE pDevice = ddi_get_driver_private(pDip);
+ if (RT_UNLIKELY(!pDevice))
+ return DDI_FAILURE;
+
+ if (enmCmd != DDI_DETACH)
+ {
+ LogRel((VIRTIOLOGNAME ":VirtioDetach: Invalid enmCmd=%#x expected DDI_DETACH.\n", enmCmd));
+ return DDI_FAILURE;
+ }
+
+ int rc = pDevice->pDeviceOps->pfnDetach(pDevice);
+ if (rc == DDI_SUCCESS)
+ {
+ pDevice->pHyperOps->pfnDetach(pDevice);
+ pDevice->pDeviceOps->pfnFree(pDevice);
+ pDevice->pvDevice = NULL;
+ pDevice->pHyperOps->pfnFree(pDevice);
+ pDevice->pvHyper = NULL;
+
+ ddi_set_driver_private(pDevice->pDip, NULL);
+ RTMemFree(pDevice);
+ return DDI_SUCCESS;
+ }
+ else
+ LogRel((VIRTIOLOGNAME ":VirtioDetach: DeviceOps pfnDetach failed. rc=%d\n", rc));
+
+ return DDI_FAILURE;
+}
+
+
+/**
+ * Allocates a Virtio Queue object and assigns it an index.
+ *
+ * @param pDevice Pointer to the Virtio device instance.
+ *
+ * @return A pointer to a Virtio Queue instance.
+ */
+PVIRTIOQUEUE VirtioGetQueue(PVIRTIODEVICE pDevice, uint16_t Index)
+{
+ PVIRTIOQUEUE pQueue = RTMemAllocZ(sizeof(VIRTIOQUEUE));
+ if (RT_UNLIKELY(!pQueue))
+ {
+ LogRel((VIRTIOLOGNAME ":VirtioGetQueue: failed to alloc memory for %u bytes.\n", sizeof(VIRTIOQUEUE)));
+ return NULL;
+ }
+
+ pQueue->QueueIndex = Index;
+ pQueue->pvData = pDevice->pHyperOps->pfnGetQueue(pDevice, pQueue);
+ if (RT_UNLIKELY(!pQueue->pvData))
+ {
+ LogRel((VIRTIOLOGNAME ":VirtioGetQueue: HyperOps GetQueue failed!\n"));
+ RTMemFree(pQueue);
+ return NULL;
+ }
+
+ AssertReturn(pQueue->pQueue, NULL);
+ AssertReturn(pQueue->Ring.cDesc > 0, NULL);
+
+ /* @todo enable interrupt. */
+
+ return pQueue;
+}
+
+
+/**
+ * Puts a queue and destroys the instance.
+ *
+ * @param pDevice Pointer to the Virtio device instance.
+ * @param pQueue Pointer to the Virtio queue.
+ */
+void VirtioPutQueue(PVIRTIODEVICE pDevice, PVIRTIOQUEUE pQueue)
+{
+ AssertReturnVoid(pDevice);
+ AssertReturnVoid(pQueue);
+
+ pDevice->pHyperOps->pfnPutQueue(pDevice, pQueue);
+ RTMemFree(pQueue);
+}
+