summaryrefslogtreecommitdiffstats
path: root/src/VBox/Additions/solaris/DRM/vboxvideo_drm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Additions/solaris/DRM/vboxvideo_drm.c')
-rw-r--r--src/VBox/Additions/solaris/DRM/vboxvideo_drm.c409
1 files changed, 409 insertions, 0 deletions
diff --git a/src/VBox/Additions/solaris/DRM/vboxvideo_drm.c b/src/VBox/Additions/solaris/DRM/vboxvideo_drm.c
new file mode 100644
index 00000000..c63deb33
--- /dev/null
+++ b/src/VBox/Additions/solaris/DRM/vboxvideo_drm.c
@@ -0,0 +1,409 @@
+/* $Id: vboxvideo_drm.c $ */
+/** @file
+ * vboxvideo_drm - Direct Rendering Module, Solaris Specific Code.
+ */
+
+/*
+ * Copyright (C) 2009-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#undef offsetof /* This gets redefined in drmP.h */
+#include "include/drmP.h"
+#include "include/drm.h"
+
+#undef u /* /usr/include/sys/user.h:249:1 is where this is defined to (curproc->p_user). very cool. */
+
+#include <VBox/log.h>
+#include <VBox/version.h>
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+#define VBOXSOLQUOTE2(x) #x
+#define VBOXSOLQUOTE(x) VBOXSOLQUOTE2(x)
+/** The module name. */
+#define DEVICE_NAME "vboxvideo"
+/** The module description as seen in 'modinfo'. */
+#define DEVICE_DESC_DRV "VirtualBox DRM"
+
+/** DRM Specific defines */
+#define DRIVER_AUTHOR "Oracle Corporation"
+#define DRIVER_NAME DEVICE_NAME
+#define DRIVER_DESC DEVICE_DESC_DRV
+#define DRIVER_DATE "20090317"
+#define DRIVER_MAJOR 1
+#define DRIVER_MINOR 0
+#define DRIVER_PATCHLEVEL 0
+#define vboxvideo_PCI_IDS { 0x80ee, 0xbeef, 0, "VirtualBox Video" }, \
+ { 0, 0, 0, NULL }
+
+
+/*********************************************************************************************************************************
+* Internal Functions *
+*********************************************************************************************************************************/
+static int VBoxVideoSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd);
+static int VBoxVideoSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd);
+static int VBoxVideoSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pvArg, void **ppvResult);
+
+static void vboxVideoSolarisConfigure(drm_driver_t *pDriver);
+
+
+/*********************************************************************************************************************************
+* Structures and Typedefs *
+*********************************************************************************************************************************/
+extern struct cb_ops drm_cb_ops;
+
+/**
+ * dev_ops: for driver device operations
+ */
+static struct dev_ops g_VBoxVideoSolarisDevOps =
+{
+ DEVO_REV, /* driver build revision */
+ 0, /* ref count */
+ VBoxVideoSolarisGetInfo,
+ nulldev, /* identify */
+ nulldev, /* probe */
+ VBoxVideoSolarisAttach,
+ VBoxVideoSolarisDetach,
+ nodev, /* reset */
+ &drm_cb_ops,
+ NULL, /* dev bus ops*/
+ NULL /* power */
+};
+
+/**
+ * modldrv: export driver specifics to the kernel
+ */
+static struct modldrv g_VBoxVideoSolarisModule =
+{
+ &mod_driverops, /* extern from kernel */
+ DEVICE_DESC_DRV " " VBOX_VERSION_STRING "r" VBOXSOLQUOTE(VBOX_SVN_REV),
+ &g_VBoxVideoSolarisDevOps
+};
+
+/**
+ * modlinkage: export install/remove/info to the kernel
+ */
+static struct modlinkage g_VBoxVideoSolarisModLinkage =
+{
+ MODREV_1, /* loadable module system revision */
+ &g_VBoxVideoSolarisModule,
+ NULL /* terminate array of linkage structures */
+};
+
+/* VBoxVideo device PCI ID */
+static drm_pci_id_list_t vboxvideo_pciidlist[] = {
+ vboxvideo_PCI_IDS
+};
+
+
+/** DRM Driver */
+static drm_driver_t g_VBoxVideoSolarisDRMDriver = { 0 };
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+/** Soft state. */
+static void *g_pVBoxVideoSolarisState;
+
+
+/**
+ * Kernel entry points
+ */
+int _init(void)
+{
+ LogFlow((DEVICE_NAME ":_init flow\n"));
+ cmn_err(CE_NOTE, DEVICE_NAME ":_init\n");
+
+ vboxVideoSolarisConfigure(&g_VBoxVideoSolarisDRMDriver);
+ int rc = ddi_soft_state_init(&g_pVBoxVideoSolarisState, sizeof(drm_device_t), DRM_MAX_INSTANCES);
+ if (!rc)
+ return mod_install(&g_VBoxVideoSolarisModLinkage);
+ else
+ LogRel((DEVICE_NAME ":_init: ddi_soft_state_init failed. rc=%d\n", rc));
+}
+
+
+int _fini(void)
+{
+ LogFlow((DEVICE_NAME ":_fini flow\n"));
+ cmn_err(CE_NOTE, DEVICE_NAME ":_fini\n");
+ int rc = mod_remove(&g_VBoxVideoSolarisModLinkage);
+ if (!rc)
+ ddi_soft_state_fini(&g_pVBoxVideoSolarisState);
+ return rc;
+}
+
+
+int _info(struct modinfo *pModInfo)
+{
+ LogFlow((DEVICE_NAME ":_info flow\n"));
+ cmn_err(CE_NOTE, DEVICE_NAME ":_info\n");
+ return mod_info(&g_VBoxVideoSolarisModLinkage, pModInfo);
+}
+
+
+/**
+ * Attach entry point, to attach a device to the system or resume it.
+ *
+ * @param pDip The module structure instance.
+ * @param enmCmd Operation type (attach/resume).
+ *
+ * @returns corresponding solaris error code.
+ */
+static int VBoxVideoSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
+{
+ LogFlow((DEVICE_NAME ":VBoxVideoSolarisAttach pDip=%p enmCmd=%d\n", pDip, enmCmd));
+ cmn_err(CE_NOTE, DEVICE_NAME ":attach\n");
+
+ switch (enmCmd)
+ {
+ case DDI_ATTACH:
+ {
+ drm_device_t *pState;
+ int Instance = ddi_get_instance(pDip);
+ int rc = ddi_soft_state_zalloc(g_pVBoxVideoSolarisState, Instance);
+ if (rc == DDI_SUCCESS)
+ {
+ pState = ddi_get_soft_state(g_pVBoxVideoSolarisState, Instance);
+ pState->dip = pDip;
+ pState->driver = &g_VBoxVideoSolarisDRMDriver;
+
+ /*
+ * Register using the DRM module which will create the minor nodes
+ */
+ void *pDRMHandle = drm_supp_register(pDip, pState);
+ if (pDRMHandle)
+ {
+ pState->drm_handle = pDRMHandle;
+
+ /*
+ * Probe with our pci-id.
+ * -XXX- is probing really required???
+ */
+ pState->drm_supported = DRM_UNSUPPORT;
+ rc = drm_probe(pState, vboxvideo_pciidlist);
+ if (rc == DDI_SUCCESS)
+ {
+ pState->drm_supported = DRM_SUPPORT;
+
+ /*
+ * Call the common attach DRM routine.
+ */
+ rc = drm_attach(pState);
+ if (rc == DDI_SUCCESS)
+ {
+ return DDI_SUCCESS;
+ }
+ else
+ LogRel((DEVICE_NAME ":VBoxVideoSolarisAttach drm_attach failed.rc=%d\n", rc));
+ }
+ else
+ LogRel((DEVICE_NAME ":VBoxVideoSolarisAttach drm_probe failed.rc=%d\n", rc));
+
+ drm_supp_unregister(pDRMHandle);
+ }
+ else
+ LogRel((DEVICE_NAME ":VBoxVideoSolarisAttach drm_supp_register failed.\n"));
+
+ ddi_soft_state_free(g_pVBoxVideoSolarisState, Instance);
+ }
+ else
+ LogRel((DEVICE_NAME ":VBoxVideoSolarisAttach failed to alloc memory for soft state.rc=%d\n", rc));
+ return DDI_FAILURE;
+ }
+
+ case DDI_RESUME:
+ {
+ /* Nothing to do here... */
+ return DDI_SUCCESS;
+ }
+ }
+ return DDI_FAILURE;
+}
+
+
+/**
+ * Detach entry point, to detach a device to the system or suspend it.
+ *
+ * @param pDip The module structure instance.
+ * @param enmCmd Operation type (detach/suspend).
+ *
+ * @returns corresponding solaris error code.
+ */
+static int VBoxVideoSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
+{
+ LogFlow((DEVICE_NAME ":VBoxVideoSolarisDetach pDip=%p enmCmd=%d\n", pDip, enmCmd));
+
+ switch (enmCmd)
+ {
+ case DDI_DETACH:
+ {
+ int Instance = ddi_get_instance(pDip);
+ drm_device_t *pState = ddi_get_soft_state(g_pVBoxVideoSolarisState, Instance);
+ if (pState)
+ {
+ drm_detach(pState);
+ drm_supp_unregister(pState->drm_handle);
+ ddi_soft_state_free(g_pVBoxVideoSolarisState, Instance);
+ return DDI_SUCCESS;
+ }
+ else
+ LogRel((DEVICE_NAME ":VBoxVideoSolarisDetach failed to get soft state.\n"));
+
+ return DDI_FAILURE;
+ }
+
+ case DDI_RESUME:
+ {
+ /* Nothing to do here... */
+ return DDI_SUCCESS;
+ }
+ }
+ return DDI_FAILURE;
+}
+
+
+/*
+ * Info entry point, called by solaris kernel for obtaining driver info.
+ *
+ * @param pDip The module structure instance (do not use).
+ * @param enmCmd Information request type.
+ * @param pvArg Type specific argument.
+ * @param ppvResult Where to store the requested info.
+ *
+ * @return corresponding solaris error code.
+ */
+static int VBoxVideoSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pvArg, void **ppvResult)
+{
+ LogFlow((DEVICE_NAME ":VBoxGuestSolarisGetInfo\n"));
+
+ int rc = DDI_FAILURE;
+ int Instance = drm_dev_to_instance((dev_t)pvArg);
+ drm_device_t *pState = NULL;
+ switch (enmCmd)
+ {
+ case DDI_INFO_DEVT2DEVINFO:
+ {
+ pState = ddi_get_soft_state(g_pVBoxVideoSolarisState, Instance);
+ if ( pState
+ && pState->dip)
+ {
+ *ppvResult = (void *)pState->dip;
+ rc = DDI_SUCCESS;
+ }
+ else
+ {
+ LogRel((DEVICE_NAME ":VBoxGuestSolarisGetInfo state or state's devinfo invalid.\n"));
+ rc = DDI_FAILURE;
+ }
+ break;
+ }
+
+ case DDI_INFO_DEVT2INSTANCE:
+ {
+ *ppvResult = (void *)(uintptr_t)Instance;
+ rc = DDI_SUCCESS;
+ break;
+ }
+
+ default:
+ {
+ rc = DDI_FAILURE;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+
+static int vboxVideoSolarisLoad(drm_device_t *pDevice, unsigned long fFlag)
+{
+ return 0;
+}
+
+static int vboxVideoSolarisUnload(drm_device_t *pDevice)
+{
+ return 0;
+}
+
+static void vboxVideoSolarisLastClose(drm_device_t *pDevice)
+{
+}
+
+static void vboxVideoSolarisPreClose(drm_device_t *pDevice, drm_file_t *pFile)
+{
+}
+
+
+static void vboxVideoSolarisConfigure(drm_driver_t *pDriver)
+{
+ /*
+ * DRM entry points, use the common DRM extension wherever possible.
+ */
+ pDriver->buf_priv_size = 1;
+ pDriver->load = vboxVideoSolarisLoad;
+ pDriver->unload = vboxVideoSolarisUnload;
+ pDriver->preclose = vboxVideoSolarisPreClose;
+ pDriver->lastclose = vboxVideoSolarisLastClose;
+ pDriver->device_is_agp = drm_device_is_agp;
+#if 0
+ pDriver->get_vblank_counter = drm_vblank_count;
+ pDriver->enable_vblank = NULL;
+ pDriver->disable_vblank = NULL;
+ pDriver->irq_install = drm_driver_irq_install;
+ pDriver->irq_preinstall = drm_driver_irq_preinstall;
+ pDriver->irq_postinstall = drm_driver_irq_postinstall;
+ pDirver->irq_uninstall = drm_driver_irq_uninstall;
+ pDriver->irq_handler = drm_driver_irq_handler;
+
+ pDriver->driver_ioctls =
+ pDriver->max_driver_ioctls =
+#endif
+
+ pDriver->driver_name = DRIVER_NAME;
+ pDriver->driver_desc = DRIVER_DESC;
+ pDriver->driver_date = DRIVER_DATE;
+ pDriver->driver_major = DRIVER_MAJOR;
+ pDriver->driver_minor = DRIVER_MINOR;
+ pDriver->driver_patchlevel = DRIVER_PATCHLEVEL;
+
+ pDriver->use_agp = 1;
+ pDriver->require_agp = 1;
+ pDriver->use_irq = 1;
+}
+