VBoxGuest-solaris.c revision bfd2448384a97d1c16a54af5d1523ae1b861ce26
11d3005e2935c925665896fa26fde09b3e656d70vboxsync/* $Id$ */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** @file
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * VirtualBox Guest Additions Driver for Solaris.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync/*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Copyright (C) 2007 Sun Microsystems, Inc.
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync *
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * available from http://www.virtualbox.org. This file is free software;
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * you can redistribute it and/or modify it under the terms of the GNU
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * General Public License (GPL) as published by the Free Software
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
cf5f6bf2704d4fff443139e10bccc6a0a7fa4b85vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * additional information or have any questions.
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync */
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/*******************************************************************************
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync* Header Files *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync*******************************************************************************/
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <sys/conf.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <sys/modctl.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <sys/mutex.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <sys/pci.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <sys/stat.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <sys/ddi.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <sys/ddi_intr.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <sys/sunddi.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <sys/open.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#undef u /* /usr/include/sys/user.h:249:1 is where this is defined to (curproc->p_user). very cool. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include "VBoxGuestInternal.h"
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <VBox/log.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <VBox/version.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/assert.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/initterm.h>
aef51041e0fe31e8ea903dd7e67fe12cef645654vboxsync#include <iprt/process.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include <iprt/mem.h>
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/*******************************************************************************
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync* Defined Constants And Macros *
aef51041e0fe31e8ea903dd7e67fe12cef645654vboxsync*******************************************************************************/
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#define VBOXSOLQUOTE2(x) #x
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#define VBOXSOLQUOTE(x) VBOXSOLQUOTE2(x)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** The module name. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#define DEVICE_NAME "vboxguest"
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** The module description as seen in 'modinfo'. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#define DEVICE_DESC "VirtualBox GstDrv"
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync/*******************************************************************************
79baed6836ae36c5f15b182292387484dcf7a752vboxsync* Internal Functions *
79baed6836ae36c5f15b182292387484dcf7a752vboxsync*******************************************************************************/
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred);
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisClose(dev_t Dev, int fFlag, int fType, cred_t *pCred);
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred);
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred);
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pArg, void **ppResult);
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd);
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisAddIRQ(dev_info_t *pDip, void *pvState);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic void VBoxGuestSolarisRemoveIRQ(dev_info_t *pDip, void *pvState);
aef51041e0fe31e8ea903dd7e67fe12cef645654vboxsyncstatic uint_t VBoxGuestSolarisISR(caddr_t Arg);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/*******************************************************************************
79baed6836ae36c5f15b182292387484dcf7a752vboxsync* Structures and Typedefs *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync*******************************************************************************/
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * cb_ops: for drivers that support char/block entry points
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic struct cb_ops g_VBoxGuestSolarisCbOps =
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBoxGuestSolarisOpen,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBoxGuestSolarisClose,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync nodev, /* b strategy */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync nodev, /* b dump */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync nodev, /* b print */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBoxGuestSolarisRead,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBoxGuestSolarisWrite,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBoxGuestSolarisIOCtl,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync nodev, /* c devmap */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync nodev, /* c mmap */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync nodev, /* c segmap */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync nochpoll, /* c poll */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_prop_op, /* property ops */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync NULL, /* streamtab */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync D_NEW | D_MP, /* compat. flag */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync CB_REV /* revision */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync};
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * dev_ops: for driver device operations
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic struct dev_ops g_VBoxGuestSolarisDevOps =
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync DEVO_REV, /* driver build revision */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync 0, /* ref count */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBoxGuestSolarisGetInfo,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync nulldev, /* identify */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync nulldev, /* probe */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBoxGuestSolarisAttach,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBoxGuestSolarisDetach,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync nodev, /* reset */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync &g_VBoxGuestSolarisCbOps,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync (struct bus_ops *)0,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync nodev /* power */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync};
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * modldrv: export driver specifics to the kernel
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic struct modldrv g_VBoxGuestSolarisModule =
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync &mod_driverops, /* extern from kernel */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync DEVICE_DESC " " VBOX_VERSION_STRING "r" VBOXSOLQUOTE(VBOX_SVN_REV),
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync &g_VBoxGuestSolarisDevOps
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync};
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * modlinkage: export install/remove/info to the kernel
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic struct modlinkage g_VBoxGuestSolarisModLinkage =
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync MODREV_1, /* loadable module system revision */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync &g_VBoxGuestSolarisModule,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync NULL /* terminate array of linkage structures */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync};
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * State info for each open file handle.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsynctypedef struct
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** IO port handle. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_acc_handle_t PciIOHandle;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** MMIO handle. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_acc_handle_t PciMMIOHandle;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#if 0
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Interrupt block cookie. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_iblock_cookie_t BlockCookie;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#endif
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Driver Mutex. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync kmutex_t Mtx;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** IO Port. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync uint16_t uIOPortBase;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Address of the MMIO region.*/
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync caddr_t pMMIOBase;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Size of the MMIO region. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync off_t cbMMIO;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** VMMDev Version. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync uint32_t u32Version;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Pointer to the interrupt handle vector */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_intr_handle_t *pIntr;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Number of actually allocated interrupt handles */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync size_t cIntrAllocated;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#ifndef USE_SESSION_HASH
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** Pointer to the session handle. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PVBOXGUESTSESSION pSession;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#endif
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync} vboxguest_state_t;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/*******************************************************************************
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync* Global Variables *
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync*******************************************************************************/
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Device handle (we support only one instance). */
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsyncstatic dev_info_t *g_pDip;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync/** Opaque pointer to state */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic void *g_pVBoxGuestSolarisState;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Device extention & session data association structure. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic VBOXGUESTDEVEXT g_DevExt;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Spinlock protecting g_apSessionHashTab. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#ifdef USE_SESSION_HASH
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync/** Hash table */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic PVBOXGUESTSESSION g_apSessionHashTab[19];
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** Calculates the index into g_apSessionHashTab.*/
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#define SESSION_HASH(sfn) ((sfn) % RT_ELEMENTS(g_apSessionHashTab))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#endif /* USE_SESSION_HASH */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#if 0/** @todo This shouldn't be needed. if it is, that means exceptions hasn't been disabled correctly. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/** GCC C++ hack. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncunsigned __gxx_personality_v0 = 0xdecea5ed;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#endif
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Kernel entry points
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncint _init(void)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogFlow((DEVICE_NAME ":_init\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rc = ddi_soft_state_init(&g_pVBoxGuestSolarisState, sizeof(vboxguest_state_t), 1);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!rc)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = mod_install(&g_VBoxGuestSolarisModLinkage);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (rc)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_soft_state_fini(&g_pVBoxGuestSolarisState);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return rc;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncint _fini(void)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogFlow((DEVICE_NAME ":_fini\n"));
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync int rc = mod_remove(&g_VBoxGuestSolarisModLinkage);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!rc)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_soft_state_fini(&g_pVBoxGuestSolarisState);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return rc;
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncint _info(struct modinfo *pModInfo)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogFlow((DEVICE_NAME ":_info\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return mod_info(&g_VBoxGuestSolarisModLinkage, pModInfo);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Attach entry point, to attach a device to the system or resume it.
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pDip The module structure instance.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param enmCmd Attach type (ddi_attach_cmd_t)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @return corresponding solaris error code.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic int VBoxGuestSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogFlow((DEVICE_NAME "::Attach\n"));
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync switch (enmCmd)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync case DDI_ATTACH:
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rc;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int instance;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync vboxguest_state_t *pState;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync instance = ddi_get_instance(pDip);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#ifdef USE_SESSION_HASH
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = ddi_soft_state_zalloc(g_pVBoxGuestSolarisState, instance);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (rc != DDI_SUCCESS)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Log((DEVICE_NAME ":ddi_soft_state_zalloc failed.\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_FAILURE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, instance);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pState)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_soft_state_free(g_pVBoxGuestSolarisState, instance);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Log((DEVICE_NAME ":ddi_get_soft_state for instance %d failed\n", instance));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_FAILURE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pState = RTMemAllocZ(sizeof(vboxguest_state_t));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pState)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Log((DEVICE_NAME ":RTMemAllocZ failed to allocate %d bytes\n", sizeof(vboxguest_state_t)));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_FAILURE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#endif
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = RTR0Init(0);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (RT_FAILURE(rc))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Log((DEVICE_NAME ":RTR0Init failed.\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_FAILURE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Initialize the session hash table.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = RTSpinlockCreate(&g_Spinlock);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (RT_SUCCESS(rc))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Enable resources for PCI access.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_acc_handle_t PciHandle;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = pci_config_setup(pDip, &PciHandle);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (rc == DDI_SUCCESS)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Map the register address space.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync caddr_t baseAddr;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_device_acc_attr_t deviceAttr;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync deviceAttr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync deviceAttr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync deviceAttr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync deviceAttr.devacc_attr_access = DDI_DEFAULT_ACC;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = ddi_regs_map_setup(pDip, 1, &baseAddr, 0, 0, &deviceAttr, &pState->PciIOHandle);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (rc == DDI_SUCCESS)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Read size of the MMIO region.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pState->uIOPortBase = (uintptr_t)baseAddr;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = ddi_dev_regsize(pDip, 2, &pState->cbMMIO);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (rc == DDI_SUCCESS)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = ddi_regs_map_setup(pDip, 2, &pState->pMMIOBase, 0, pState->cbMMIO, &deviceAttr,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync &pState->PciMMIOHandle);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (rc == DDI_SUCCESS)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Add IRQ of VMMDev.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = VBoxGuestSolarisAddIRQ(pDip, pState);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (rc == DDI_SUCCESS)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Call the common device extension initializer.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = VBoxGuestInitDevExt(&g_DevExt, pState->uIOPortBase, pState->pMMIOBase,
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pState->cbMMIO, VBOXOSTYPE_Solaris);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (RT_SUCCESS(rc))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
58ab0ad45444e80bdd970ddeb468d0872dbbbb47vboxsync rc = ddi_create_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0);
11d3005e2935c925665896fa26fde09b3e656d70vboxsync if (rc == DDI_SUCCESS)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
58ab0ad45444e80bdd970ddeb468d0872dbbbb47vboxsync g_pDip = pDip;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_set_driver_private(pDip, pState);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pci_config_teardown(&PciHandle);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_report_dev(pDip);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_SUCCESS;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogRel((DEVICE_NAME ": ddi_create_minor_node failed.\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBoxGuestDeleteDevExt(&g_DevExt);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogRel((DEVICE_NAME ": VBoxGuestInitDevExt failed.\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBoxGuestSolarisRemoveIRQ(pDip, pState);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogRel((DEVICE_NAME ": VBoxGuestSolarisAddIRQ failed.\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_regs_map_free(&pState->PciMMIOHandle);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogRel((DEVICE_NAME ": ddi_regs_map_setup for MMIO region failed.\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogRel((DEVICE_NAME ": ddi_dev_regsize for MMIO region failed.\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_regs_map_free(&pState->PciIOHandle);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogRel((DEVICE_NAME ": ddi_regs_map_setup for IOport failed.\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pci_config_teardown(&PciHandle);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogRel((DEVICE_NAME ": pci_config_setup failed rc=%d.\n", rc));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTSpinlockDestroy(g_Spinlock);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync g_Spinlock = NIL_RTSPINLOCK;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogRel((DEVICE_NAME ": RTSpinlockCreate failed.\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTR0Term();
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_FAILURE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync case DDI_RESUME:
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
58ab0ad45444e80bdd970ddeb468d0872dbbbb47vboxsync /** @todo implement resume for guest driver. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_SUCCESS;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync default:
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_FAILURE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
58ab0ad45444e80bdd970ddeb468d0872dbbbb47vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Detach entry point, to detach a device to the system or suspend it.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pDip The module structure instance.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param enmCmd Attach type (ddi_attach_cmd_t)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @return corresponding solaris error code.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic int VBoxGuestSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogFlow((DEVICE_NAME "::Detach\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync switch (enmCmd)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync case DDI_DETACH:
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rc;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int instance = ddi_get_instance(pDip);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#ifdef USE_SESSION_HASH
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, instance);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync vboxguest_state_t *pState = ddi_get_driver_private(g_pDip);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#endif
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (pState)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBoxGuestSolarisRemoveIRQ(pDip, pState);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_regs_map_free(&pState->PciIOHandle);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_regs_map_free(&pState->PciMMIOHandle);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_remove_minor_node(pDip, NULL);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#ifdef USE_SESSION_HASH
58ab0ad45444e80bdd970ddeb468d0872dbbbb47vboxsync ddi_soft_state_free(g_pVBoxGuestSolarisState, instance);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTMemFree(pState);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#endif
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = RTSpinlockDestroy(g_Spinlock);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync AssertRC(rc);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync g_Spinlock = NIL_RTSPINLOCK;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTR0Term();
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_SUCCESS;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Log((DEVICE_NAME ":ddi_get_soft_state failed. Cannot detach instance %d\n", instance));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_FAILURE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync case DDI_SUSPEND:
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /** @todo implement suspend for guest driver. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_SUCCESS;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync default:
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return DDI_FAILURE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Info entry point, called by solaris kernel for obtaining driver info.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pDip The module structure instance (do not use).
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param enmCmd Information request type.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pvArg Type specific argument.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param ppvResult Where to store the requested info.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @return corresponding solaris error code.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic int VBoxGuestSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pvArg, void **ppvResult)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogFlow((DEVICE_NAME "::GetInfo\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rc = DDI_SUCCESS;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync switch (enmCmd)
11d3005e2935c925665896fa26fde09b3e656d70vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync case DDI_INFO_DEVT2DEVINFO:
11d3005e2935c925665896fa26fde09b3e656d70vboxsync *ppvResult = (void *)g_pDip;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync break;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync case DDI_INFO_DEVT2INSTANCE:
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync *ppvResult = (void *)(uintptr_t)ddi_get_instance(g_pDip);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync break;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync default:
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = DDI_FAILURE;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync break;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync NOREF(pvArg);
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync return rc;
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync}
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * User context entry points
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic int VBoxGuestSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int rc;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PVBOXGUESTSESSION pSession;
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync
e6a3673a23c632af5208dcc8a37f45d7a20b0554vboxsync LogFlow((DEVICE_NAME "::Open\n"));
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync * Verify we are being opened as a character device.
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync */
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync if (fType != OTYP_CHR)
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync return EINVAL;
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync#ifndef USE_SESSION_HASH
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync vboxguest_state_t *pState = NULL;
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync unsigned iOpenInstance;
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++)
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync {
178b942cb42a13f3bca0f99a1bca1311ae190ffdvboxsync if ( !ddi_get_soft_state(g_pVBoxGuestSolarisState, iOpenInstance) /* faster */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync && ddi_soft_state_zalloc(g_pVBoxGuestSolarisState, iOpenInstance) == DDI_SUCCESS)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, iOpenInstance);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync break;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pState)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Log((DEVICE_NAME "::Open: too many open instances."));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return ENXIO;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Create a new session.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = VBoxGuestCreateUserSession(&g_DevExt, &pSession);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (RT_SUCCESS(rc))
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync {
befced03fd84a13590b8ce8be8c2480e9bc568c6vboxsync pState->pSession = pSession;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *pDev = makedevice(getmajor(*pDev), iOpenInstance);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Log((DEVICE_NAME "::Open: pSession=%p pState=%p pid=%d\n", pSession, pState, (int)RTProcSelf()));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return 0;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /* Failed, clean up. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync ddi_soft_state_free(g_pVBoxGuestSolarisState, iOpenInstance);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Create a new session.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = VBoxGuestCreateUserSession(&g_DevExt, &pSession);
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync if (RT_SUCCESS(rc))
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync {
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync /*
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync * Insert it into the hash table.
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync */
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync unsigned iHash = SESSION_HASH(pSession->Process);
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync pSession->pNextHash = g_apSessionHashTab[iHash];
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync g_apSessionHashTab[iHash] = pSession;
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync int instance;
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync for (instance = 0; instance < 4096; instance++)
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync {
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, instance);
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync if (pState)
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync break;
16d723d9d597f4872dd4c2c960af9cbca4ed63bdvboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if (instance >= 4096)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync {
79baed6836ae36c5f15b182292387484dcf7a752vboxsync Log((DEVICE_NAME "::Open: All instances exhausted\n"));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return ENXIO;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync *pDev = makedevice(getmajor(*pDev), instance);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync Log((DEVICE_NAME "::Open success: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return 0;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync#endif
79baed6836ae36c5f15b182292387484dcf7a752vboxsync LogRel((DEVICE_NAME "::Open: VBoxGuestCreateUserSession failed. rc=%d\n", rc));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return EFAULT;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync}
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisClose(dev_t Dev, int flag, int fType, cred_t *pCred)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync{
79baed6836ae36c5f15b182292387484dcf7a752vboxsync LogFlow((DEVICE_NAME "::Close pid=%d\n", (int)RTProcSelf()));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync#ifndef USE_SESSION_HASH
79baed6836ae36c5f15b182292387484dcf7a752vboxsync PVBOXGUESTSESSION pSession;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, getminor(Dev));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if (!pState)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync {
79baed6836ae36c5f15b182292387484dcf7a752vboxsync Log((DEVICE_NAME "::Close: failed to get pState.\n"));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return EFAULT;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pSession = pState->pSession;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pState->pSession = NULL;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync Log((DEVICE_NAME "::Close: pSession=%p pState=%p\n", pSession, pState));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync ddi_soft_state_free(g_pVBoxGuestSolarisState, getminor(Dev));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if (!pSession)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync {
79baed6836ae36c5f15b182292387484dcf7a752vboxsync Log((DEVICE_NAME "::Close: failed to get pSession.\n"));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return EFAULT;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync#else /* USE_SESSION_HASH */
79baed6836ae36c5f15b182292387484dcf7a752vboxsync /*
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * Remove from the hash table.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync */
79baed6836ae36c5f15b182292387484dcf7a752vboxsync PVBOXGUESTSESSION pSession;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync const RTPROCESS Process = RTProcSelf();
79baed6836ae36c5f15b182292387484dcf7a752vboxsync const unsigned iHash = SESSION_HASH(Process);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync pSession = g_apSessionHashTab[iHash];
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if (pSession)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (pSession->Process == Process)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync g_apSessionHashTab[iHash] = pSession->pNextHash;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pSession->pNextHash = NULL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PVBOXGUESTSESSION pPrev = pSession;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pSession = pSession->pNextHash;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync while (pSession)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (pSession->Process == Process)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
11d3005e2935c925665896fa26fde09b3e656d70vboxsync pPrev->pNextHash = pSession->pNextHash;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pSession->pNextHash = NULL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync break;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /* next */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pPrev = pSession;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pSession = pSession->pNextHash;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync }
79baed6836ae36c5f15b182292387484dcf7a752vboxsync RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if (!pSession)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync Log((DEVICE_NAME "::Close: WHUT?!? pSession == NULL! This must be a mistake... pid=%d", (int)Process));
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync return EFAULT;
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync }
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync Log((DEVICE_NAME "::Close: pid=%d\n", (int)Process));
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync#endif /* USE_SESSION_HASH */
69c6eff4fcb6dc027e94a3e7908926c4e8ef5aefvboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync /*
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * Close the session.
79baed6836ae36c5f15b182292387484dcf7a752vboxsync */
79baed6836ae36c5f15b182292387484dcf7a752vboxsync VBoxGuestCloseSession(&g_DevExt, pSession);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return 0;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync}
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync{
79baed6836ae36c5f15b182292387484dcf7a752vboxsync LogFlow((DEVICE_NAME "::Read\n"));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return 0;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync}
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsyncstatic int VBoxGuestSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync{
79baed6836ae36c5f15b182292387484dcf7a752vboxsync LogFlow((DEVICE_NAME "::Write\n"));
79baed6836ae36c5f15b182292387484dcf7a752vboxsync return 0;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync}
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
79baed6836ae36c5f15b182292387484dcf7a752vboxsync/** @def IOCPARM_LEN
79baed6836ae36c5f15b182292387484dcf7a752vboxsync * Gets the length from the ioctl number.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * This is normally defined by sys/ioccom.h on BSD systems...
79baed6836ae36c5f15b182292387484dcf7a752vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#ifndef IOCPARM_LEN
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync# define IOCPARM_LEN(Code) (((Code) >> 16) & IOCPARM_MASK)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync#endif
79baed6836ae36c5f15b182292387484dcf7a752vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Driver ioctl, an alternate entry point for this character driver.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param Dev Device number
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param Cmd Operation identifier
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pArg Arguments from user to driver
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param Mode Information bitfield (read/write, address space etc.)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pCred User credentials
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pVal Return value for calling process.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @return corresponding solaris error code.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsyncstatic int VBoxGuestSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync{
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogFlow((DEVICE_NAME ":VBoxGuestSolarisIOCtl\n"));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#ifndef USE_SESSION_HASH
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Get the session from the soft state item.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, getminor(Dev));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pState)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Log((DEVICE_NAME "::IOCtl: no state data for %d\n", getminor(Dev)));
58461e707998a927c19da46b98748ee2b79f4190vboxsync return EINVAL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PVBOXGUESTSESSION pSession = pState->pSession;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (!pSession)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Log((DEVICE_NAME "::IOCtl: no session data for %d\n", getminor(Dev)));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return EINVAL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#else /* USE_SESSION_HASH */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync const RTPROCESS Process = RTProcSelf();
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync const unsigned iHash = SESSION_HASH(Process);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync PVBOXGUESTSESSION pSession;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Find the session.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pSession = g_apSessionHashTab[iHash];
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (pSession && pSession->Process != Process)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync do pSession = pSession->pNextHash;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync while (pSession && pSession->Process != Process);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
11d3005e2935c925665896fa26fde09b3e656d70vboxsync if (!pSession)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Log((DEVICE_NAME "::IOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n", (int)Process, Cmd));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return EINVAL;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#endif /* USE_SESSION_HASH */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync /*
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * Read and validate the request wrapper.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync VBGLBIGREQ ReqWrap;
79baed6836ae36c5f15b182292387484dcf7a752vboxsync if (IOCPARM_LEN(Cmd) != sizeof(ReqWrap))
79baed6836ae36c5f15b182292387484dcf7a752vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync LogRel((DEVICE_NAME "::IOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap)));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return ENOTTY;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync int rc = ddi_copyin((void *)pArg, &ReqWrap, sizeof(ReqWrap), Mode);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (RT_UNLIKELY(rc))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::IOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%d.\n", pArg, Cmd, rc));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return EINVAL;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync if (ReqWrap.u32Magic != VBGLBIGREQ_MAGIC)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::IOCtl: bad magic %#x; pArg=%p Cmd=%d.\n", ReqWrap.u32Magic, pArg, Cmd));
27152389a84c6dec057fba6fc21241991e079006vboxsync return EINVAL;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (RT_UNLIKELY( ReqWrap.cbData == 0
27152389a84c6dec057fba6fc21241991e079006vboxsync || ReqWrap.cbData > _1M*16))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync Log((DEVICE_NAME "::IOCtl: bad size %#x; pArg=%p Cmd=%d.\n", ReqWrap.cbData, pArg, Cmd));
27152389a84c6dec057fba6fc21241991e079006vboxsync return EINVAL;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Read the request.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync void *pvBuf = RTMemTmpAlloc(ReqWrap.cbData);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (RT_UNLIKELY(!pvBuf))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::IOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap.cbData));
27152389a84c6dec057fba6fc21241991e079006vboxsync return ENOMEM;
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = ddi_copyin((void *)(uintptr_t)ReqWrap.pvDataR3, pvBuf, ReqWrap.cbData, Mode);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (RT_UNLIKELY(rc))
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTMemTmpFree(pvBuf);
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::IOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
27152389a84c6dec057fba6fc21241991e079006vboxsync return EFAULT;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (RT_UNLIKELY( ReqWrap.cbData != 0
27152389a84c6dec057fba6fc21241991e079006vboxsync && !VALID_PTR(pvBuf)))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync RTMemTmpFree(pvBuf);
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::IOCtl: pvBuf invalid pointer %p\n", pvBuf));
27152389a84c6dec057fba6fc21241991e079006vboxsync return EINVAL;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync Log((DEVICE_NAME "::IOCtl: pSession=%p pid=%d.\n", pSession, (int)RTProcSelf()));
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * Process the IOCtl.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync size_t cbDataReturned;
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = VBoxGuestCommonIOCtl(Cmd, &g_DevExt, pSession, pvBuf, ReqWrap.cbData, &cbDataReturned);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (RT_SUCCESS(rc))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = 0;
27152389a84c6dec057fba6fc21241991e079006vboxsync if (RT_UNLIKELY(cbDataReturned > ReqWrap.cbData))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::IOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData));
27152389a84c6dec057fba6fc21241991e079006vboxsync cbDataReturned = ReqWrap.cbData;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync if (cbDataReturned > 0)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = ddi_copyout(pvBuf, (void *)(uintptr_t)ReqWrap.pvDataR3, cbDataReturned, Mode);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (RT_UNLIKELY(rc))
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::IOCtl: ddi_copyout failed; pvBuf=%p pArg=%p cbDataReturned=%u Cmd=%d. rc=%d\n",
27152389a84c6dec057fba6fc21241991e079006vboxsync pvBuf, pArg, cbDataReturned, Cmd, rc));
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = EFAULT;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync }
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::IOCtl: VBoxGuestCommonIOCtl failed. rc=%d\n", rc));
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync rc = RTErrConvertToErrno(rc);
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync *pVal = rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync RTMemTmpFree(pvBuf);
27152389a84c6dec057fba6fc21241991e079006vboxsync return rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Sets IRQ for VMMDev.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns Solaris error code.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pDip Pointer to the device info structure.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pvState Pointer to the state info structure.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncstatic int VBoxGuestSolarisAddIRQ(dev_info_t *pDip, void *pvState)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync LogFlow((DEVICE_NAME "::AddIRQ: %p\n", pvState));
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync vboxguest_state_t *pState = (vboxguest_state_t *)pvState;
27152389a84c6dec057fba6fc21241991e079006vboxsync#if 0
27152389a84c6dec057fba6fc21241991e079006vboxsync /*
27152389a84c6dec057fba6fc21241991e079006vboxsync * These calls are supposedly deprecated. But Sun seems to use them all over
27152389a84c6dec057fba6fc21241991e079006vboxsync * the place. Anyway, once this works we will switch to the highly elaborate
27152389a84c6dec057fba6fc21241991e079006vboxsync * and non-obsolete way of setting up IRQs.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsync int rc = ddi_get_iblock_cookie(pDip, 0, &pState->BlockCookie);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (rc == DDI_SUCCESS)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync mutex_init(&pState->Mtx, "VBoxGuest Driver Mutex", MUTEX_DRIVER, (void *)pState->BlockCookie);
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = ddi_add_intr(pDip, 0, &pState->BlockCookie, NULL, VBoxGuestSolarisISR, (caddr_t)pState);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (rc != DDI_SUCCESS)
27152389a84c6dec057fba6fc21241991e079006vboxsync Log((DEVICE_NAME ":ddi_add_intr failed. Cannot set IRQ for VMMDev.\n"));
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync else
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync Log((DEVICE_NAME ":ddi_get_iblock_cookie failed. Cannot set IRQ for VMMDev.\n"));
27152389a84c6dec057fba6fc21241991e079006vboxsync return rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync#else
27152389a84c6dec057fba6fc21241991e079006vboxsync int IntrType = 0;
27152389a84c6dec057fba6fc21241991e079006vboxsync int rc = ddi_intr_get_supported_types(pDip, &IntrType);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (rc == DDI_SUCCESS)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync /* We won't need to bother about MSIs. */
27152389a84c6dec057fba6fc21241991e079006vboxsync if (IntrType & DDI_INTR_TYPE_FIXED)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync int IntrCount = 0;
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = ddi_intr_get_nintrs(pDip, IntrType, &IntrCount);
27152389a84c6dec057fba6fc21241991e079006vboxsync if ( rc == DDI_SUCCESS
27152389a84c6dec057fba6fc21241991e079006vboxsync && IntrCount > 0)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync int IntrAvail = 0;
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = ddi_intr_get_navail(pDip, IntrType, &IntrAvail);
27152389a84c6dec057fba6fc21241991e079006vboxsync if ( rc == DDI_SUCCESS
27152389a84c6dec057fba6fc21241991e079006vboxsync && IntrAvail > 0)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync /* Allocated kernel memory for the interrupt handles. The allocation size is stored internally. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync pState->pIntr = RTMemAlloc(IntrCount * sizeof(ddi_intr_handle_t));
27152389a84c6dec057fba6fc21241991e079006vboxsync if (pState->pIntr)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync int IntrAllocated;
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = ddi_intr_alloc(pDip, pState->pIntr, IntrType, 0, IntrCount, &IntrAllocated, DDI_INTR_ALLOC_NORMAL);
27152389a84c6dec057fba6fc21241991e079006vboxsync if ( rc == DDI_SUCCESS
27152389a84c6dec057fba6fc21241991e079006vboxsync && IntrAllocated > 0)
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync pState->cIntrAllocated = IntrAllocated;
27152389a84c6dec057fba6fc21241991e079006vboxsync uint_t uIntrPriority;
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = ddi_intr_get_pri(pState->pIntr[0], &uIntrPriority);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (rc == DDI_SUCCESS)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync /* Initialize the mutex. */
27152389a84c6dec057fba6fc21241991e079006vboxsync mutex_init(&pState->Mtx, "VBoxGuestMtx", MUTEX_DRIVER, DDI_INTR_PRI(uIntrPriority));
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /* Assign interrupt handler functions and enable interrupts. */
27152389a84c6dec057fba6fc21241991e079006vboxsync for (int i = 0; i < IntrAllocated; i++)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = ddi_intr_add_handler(pState->pIntr[i], (ddi_intr_handler_t *)VBoxGuestSolarisISR,
27152389a84c6dec057fba6fc21241991e079006vboxsync (caddr_t)pState, NULL);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (rc == DDI_SUCCESS)
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = ddi_intr_enable(pState->pIntr[i]);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (rc != DDI_SUCCESS)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync /* Changing local IntrAllocated to hold so-far allocated handles for freeing. */
27152389a84c6dec057fba6fc21241991e079006vboxsync IntrAllocated = i;
27152389a84c6dec057fba6fc21241991e079006vboxsync break;
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync if (rc == DDI_SUCCESS)
27152389a84c6dec057fba6fc21241991e079006vboxsync return rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /* Remove any assigned handlers */
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME ":failed to assign IRQs allocated=%d\n", IntrAllocated));
27152389a84c6dec057fba6fc21241991e079006vboxsync for (int x = 0; x < IntrAllocated; x++)
27152389a84c6dec057fba6fc21241991e079006vboxsync ddi_intr_remove_handler(pState->pIntr[x]);
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get priority of interrupt. rc=%d\n", rc));
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync /* Remove allocated IRQs, too bad we can free only one handle at a time. */
27152389a84c6dec057fba6fc21241991e079006vboxsync for (int k = 0; k < pState->cIntrAllocated; k++)
27152389a84c6dec057fba6fc21241991e079006vboxsync ddi_intr_free(pState->pIntr[k]);
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to allocated IRQs. count=%d\n", IntrCount));
27152389a84c6dec057fba6fc21241991e079006vboxsync RTMemFree(pState->pIntr);
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to allocated IRQs. count=%d\n", IntrCount));
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get or insufficient available IRQs. rc=%d IntrAvail=%d\n", rc, IntrAvail));
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get or insufficient number of IRQs. rc=%d IntrCount=%d\n", rc, IntrCount));
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::AddIRQ: invalid irq type. IntrType=%#x\n", IntrType));
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync else
27152389a84c6dec057fba6fc21241991e079006vboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get supported interrupt types\n"));
27152389a84c6dec057fba6fc21241991e079006vboxsync return rc;
27152389a84c6dec057fba6fc21241991e079006vboxsync#endif
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Removes IRQ for VMMDev.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync * @param pDip Pointer to the device info structure.
27152389a84c6dec057fba6fc21241991e079006vboxsync * @param pvState Opaque pointer to the state info structure.
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncstatic void VBoxGuestSolarisRemoveIRQ(dev_info_t *pDip, void *pvState)
79baed6836ae36c5f15b182292387484dcf7a752vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync vboxguest_state_t *pState = (vboxguest_state_t *)pvState;
27152389a84c6dec057fba6fc21241991e079006vboxsync LogFlow((DEVICE_NAME "::RemoveIRQ: pvState=%p\n"));
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync#if 0
27152389a84c6dec057fba6fc21241991e079006vboxsync ddi_remove_intr(pDip, 0, pState->BlockCookie);
27152389a84c6dec057fba6fc21241991e079006vboxsync mutex_destroy(&pState->Mtx);
79baed6836ae36c5f15b182292387484dcf7a752vboxsync#else
79baed6836ae36c5f15b182292387484dcf7a752vboxsync for (int i = 0; i < pState->cIntrAllocated; i++)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync int rc = ddi_intr_disable(pState->pIntr[i]);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync if (rc == DDI_SUCCESS)
27152389a84c6dec057fba6fc21241991e079006vboxsync {
27152389a84c6dec057fba6fc21241991e079006vboxsync rc = ddi_intr_remove_handler(pState->pIntr[i]);
27152389a84c6dec057fba6fc21241991e079006vboxsync if (rc == DDI_SUCCESS)
27152389a84c6dec057fba6fc21241991e079006vboxsync ddi_intr_free(pState->pIntr[i]);
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync }
27152389a84c6dec057fba6fc21241991e079006vboxsync RTMemFree(pState->pIntr);
27152389a84c6dec057fba6fc21241991e079006vboxsync mutex_destroy(&pState->Mtx);
27152389a84c6dec057fba6fc21241991e079006vboxsync#endif
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/**
27152389a84c6dec057fba6fc21241991e079006vboxsync * Interrupt Service Routine for VMMDev.
27152389a84c6dec057fba6fc21241991e079006vboxsync *
27152389a84c6dec057fba6fc21241991e079006vboxsync * @returns DDI_INTR_CLAIMED if it's our interrupt, DDI_INTR_UNCLAIMED if it isn't.
27152389a84c6dec057fba6fc21241991e079006vboxsync */
27152389a84c6dec057fba6fc21241991e079006vboxsyncstatic uint_t VBoxGuestSolarisISR(caddr_t Arg)
27152389a84c6dec057fba6fc21241991e079006vboxsync{
27152389a84c6dec057fba6fc21241991e079006vboxsync LogFlow((DEVICE_NAME "::ISR: Arg=%p\n", Arg));
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync vboxguest_state_t *pState = (vboxguest_state_t *)Arg;
27152389a84c6dec057fba6fc21241991e079006vboxsync mutex_enter(&pState->Mtx);
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync bool fOurIRQ = VBoxGuestCommonISR(&g_DevExt);
27152389a84c6dec057fba6fc21241991e079006vboxsync mutex_exit(&pState->Mtx);
27152389a84c6dec057fba6fc21241991e079006vboxsync
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync return fOurIRQ ? DDI_INTR_CLAIMED : DDI_INTR_UNCLAIMED;
27152389a84c6dec057fba6fc21241991e079006vboxsync}
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync/* Common code that depend on g_DevExt. */
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync#include "VBoxGuestIDC-unix.c.h"
2ca380caf80f0dacc65f8c996077e827318f1c69vboxsync
27152389a84c6dec057fba6fc21241991e079006vboxsync