VBoxGuest-solaris.c revision cdead8438143d4d6168ddae6cb4b7ba609ac3cdb
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* $Id$ */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync * VirtualBox Guest Additions Driver for Solaris.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2007 Sun Microsystems, Inc.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync *
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * additional information or have any questions.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Header Files *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <sys/conf.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <sys/modctl.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <sys/mutex.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <sys/pci.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <sys/stat.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <sys/ddi.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <sys/ddi_intr.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <sys/sunddi.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <sys/open.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#undef u /* /usr/include/sys/user.h:249:1 is where this is defined to (curproc->p_user). very cool. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync#include "VBoxGuestInternal.h"
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync#include <VBox/log.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/version.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/assert.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/initterm.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/process.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/mem.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/cdefs.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/asm.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Defined Constants And Macros *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** The module name. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define DEVICE_NAME "vboxguest"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** The module description as seen in 'modinfo'. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define DEVICE_DESC "VirtualBox GstDrv"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Internal Functions *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisClose(dev_t Dev, int fFlag, int fType, cred_t *pCred);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisPoll(dev_t Dev, short fEvents, int fAnyYet, short *pReqEvents, struct pollhead **ppPollHead);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pArg, void **ppResult);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisAddIRQ(dev_info_t *pDip);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void VBoxGuestSolarisRemoveIRQ(dev_info_t *pDip);
cfb3a8ae5e9668de4506cf5c053b8009bcc89dafvboxsyncstatic uint_t VBoxGuestSolarisISR(caddr_t Arg);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Structures and Typedefs *
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * cb_ops: for drivers that support char/block entry points
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic struct cb_ops g_VBoxGuestSolarisCbOps =
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync{
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync VBoxGuestSolarisOpen,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxGuestSolarisClose,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync nodev, /* b strategy */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync nodev, /* b dump */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync nodev, /* b print */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync VBoxGuestSolarisRead,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync VBoxGuestSolarisWrite,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync VBoxGuestSolarisIOCtl,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync nodev, /* c devmap */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync nodev, /* c mmap */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync nodev, /* c segmap */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxGuestSolarisPoll,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ddi_prop_op, /* property ops */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync NULL, /* streamtab */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync D_NEW | D_MP, /* compat. flag */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CB_REV /* revision */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync};
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * dev_ops: for driver device operations
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsyncstatic struct dev_ops g_VBoxGuestSolarisDevOps =
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DEVO_REV, /* driver build revision */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync 0, /* ref count */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync VBoxGuestSolarisGetInfo,
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync nulldev, /* identify */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync nulldev, /* probe */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync VBoxGuestSolarisAttach,
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync VBoxGuestSolarisDetach,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync nodev, /* reset */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync &g_VBoxGuestSolarisCbOps,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync (struct bus_ops *)0,
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync nodev /* power */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync};
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync/**
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync * modldrv: export driver specifics to the kernel
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync */
05406988cc320ac1b0971de976b6cf0c986044a9vboxsyncstatic struct modldrv g_VBoxGuestSolarisModule =
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync{
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync &mod_driverops, /* extern from kernel */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync DEVICE_DESC " " VBOX_VERSION_STRING "r" RT_XSTR(VBOX_SVN_REV),
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync &g_VBoxGuestSolarisDevOps
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync};
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync/**
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync * modlinkage: export install/remove/info to the kernel
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync */
05406988cc320ac1b0971de976b6cf0c986044a9vboxsyncstatic struct modlinkage g_VBoxGuestSolarisModLinkage =
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync{
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync MODREV_1, /* loadable module system revision */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync &g_VBoxGuestSolarisModule,
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync NULL /* terminate array of linkage structures */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync};
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * State info for each open file handle.
3d5f0ee34d7d75f349347d02f25c5abae9b197aavboxsync */
3d5f0ee34d7d75f349347d02f25c5abae9b197aavboxsynctypedef struct
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Pointer to the session handle. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXGUESTSESSION pSession;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync /** The process reference for posting signals */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync void *pvProcRef;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync} vboxguest_state_t;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Global Variables *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Device handle (we support only one instance). */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic dev_info_t *g_pDip = NULL;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync/** Opaque pointer to file-descriptor states */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void *g_pVBoxGuestSolarisState = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Device extention & session data association structure. */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsyncstatic VBOXGUESTDEVEXT g_DevExt;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** IO port handle. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic ddi_acc_handle_t g_PciIOHandle;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync/** MMIO handle. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic ddi_acc_handle_t g_PciMMIOHandle;
23de3d76e5d27015e334e6ff763ab08de5969363vboxsync/** IO Port. */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsyncstatic uint16_t g_uIOPortBase;
23de3d76e5d27015e334e6ff763ab08de5969363vboxsync/** Address of the MMIO region.*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic caddr_t g_pMMIOBase;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Size of the MMIO region. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic off_t g_cbMMIO;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** VMMDev Version. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic uint32_t g_u32Version;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Pointer to the interrupt handle vector */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic ddi_intr_handle_t *g_pIntr;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Number of actually allocated interrupt handles */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic size_t g_cIntrAllocated;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** The pollhead structure */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic pollhead_t g_PollHead;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** The IRQ Mutex */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic kmutex_t g_IrqMtx;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Kernel entry points
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncint _init(void)
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME ":_init\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Prevent module autounloading.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync modctl_t *pModCtl = mod_getctl(&g_VBoxGuestSolarisModLinkage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pModCtl)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PRTLOGGER pRelLogger;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync int rc = RTLogCreate(&pRelLogger, 0 /* fFlags */, "all",
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER, NULL);
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync if (RT_SUCCESS(rc))
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync RTLogRelSetDefaultInstance(pRelLogger);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_soft_state_init(&g_pVBoxGuestSolarisState, sizeof(vboxguest_state_t), 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!rc)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = mod_install(&g_VBoxGuestSolarisModLinkage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (rc)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ddi_soft_state_fini(&g_pVBoxGuestSolarisState);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsyncint _fini(void)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME ":_fini\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = mod_remove(&g_VBoxGuestSolarisModLinkage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!rc)
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync ddi_soft_state_fini(&g_pVBoxGuestSolarisState);
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTLogDestroy(RTLogSetDefaultInstance(NULL));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncint _info(struct modinfo *pModInfo)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME ":_info\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return mod_info(&g_VBoxGuestSolarisModLinkage, pModInfo);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Attach entry point, to attach a device to the system or resume it.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDip The module structure instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param enmCmd Attach type (ddi_attach_cmd_t)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return corresponding solaris error code.
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME "::Attach\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync switch (enmCmd)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync case DDI_ATTACH:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync if (g_pDip)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: Only one instance supported.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return DDI_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync int rc;
be9bc9b4ba510c4b4159c193f783d024633ef8e9vboxsync int instance;
be9bc9b4ba510c4b4159c193f783d024633ef8e9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync instance = ddi_get_instance(pDip);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
be9bc9b4ba510c4b4159c193f783d024633ef8e9vboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTR0Init(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log((DEVICE_NAME "::Attach: RTR0Init failed.\n"));
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync return DDI_FAILURE;
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
090f6abdd6282f48527b83162b8b441425f05e36vboxsync /*
090f6abdd6282f48527b83162b8b441425f05e36vboxsync * Enable resources for PCI access.
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync */
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync ddi_acc_handle_t PciHandle;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = pci_config_setup(pDip, &PciHandle);
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync if (rc == DDI_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Map the register address space.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync caddr_t baseAddr;
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync ddi_device_acc_attr_t deviceAttr;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync deviceAttr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
090f6abdd6282f48527b83162b8b441425f05e36vboxsync deviceAttr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
090f6abdd6282f48527b83162b8b441425f05e36vboxsync deviceAttr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
090f6abdd6282f48527b83162b8b441425f05e36vboxsync deviceAttr.devacc_attr_access = DDI_DEFAULT_ACC;
090f6abdd6282f48527b83162b8b441425f05e36vboxsync rc = ddi_regs_map_setup(pDip, 1, &baseAddr, 0, 0, &deviceAttr, &g_PciIOHandle);
090f6abdd6282f48527b83162b8b441425f05e36vboxsync if (rc == DDI_SUCCESS)
090f6abdd6282f48527b83162b8b441425f05e36vboxsync {
090f6abdd6282f48527b83162b8b441425f05e36vboxsync /*
090f6abdd6282f48527b83162b8b441425f05e36vboxsync * Read size of the MMIO region.
090f6abdd6282f48527b83162b8b441425f05e36vboxsync */
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync g_uIOPortBase = (uintptr_t)baseAddr;
090f6abdd6282f48527b83162b8b441425f05e36vboxsync rc = ddi_dev_regsize(pDip, 2, &g_cbMMIO);
090f6abdd6282f48527b83162b8b441425f05e36vboxsync if (rc == DDI_SUCCESS)
090f6abdd6282f48527b83162b8b441425f05e36vboxsync {
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync rc = ddi_regs_map_setup(pDip, 2, &g_pMMIOBase, 0, g_cbMMIO, &deviceAttr,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync &g_PciMMIOHandle);
090f6abdd6282f48527b83162b8b441425f05e36vboxsync if (rc == DDI_SUCCESS)
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Add IRQ of VMMDev.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync rc = VBoxGuestSolarisAddIRQ(pDip);
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync if (rc == DDI_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Call the common device extension initializer.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VBoxGuestInitDevExt(&g_DevExt, g_uIOPortBase, g_pMMIOBase,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync g_cbMMIO, VBOXOSTYPE_Solaris,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_create_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0);
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync if (rc == DDI_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync g_pDip = pDip;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pci_config_teardown(&PciHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return DDI_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: ddi_create_minor_node failed.\n"));
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync VBoxGuestDeleteDevExt(&g_DevExt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: VBoxGuestInitDevExt failed.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxGuestSolarisRemoveIRQ(pDip);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: VBoxGuestSolarisAddIRQ failed.\n"));
0b65654be767b9fb7677181ddb434d8467f608e3vboxsync ddi_regs_map_free(&g_PciMMIOHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync LogRel((DEVICE_NAME "::Attach: ddi_regs_map_setup for MMIO region failed.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: ddi_dev_regsize for MMIO region failed.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ddi_regs_map_free(&g_PciIOHandle);
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync }
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync else
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync LogRel((DEVICE_NAME "::Attach: ddi_regs_map_setup for IOport failed.\n"));
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync pci_config_teardown(&PciHandle);
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync }
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Attach: pci_config_setup failed rc=%d.\n", rc));
f5395a2af3050ddd694b0ad505975f7b717ab4f1vboxsync
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync RTR0Term();
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync return DDI_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case DDI_RESUME:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** @todo implement resume for guest driver. */
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync return DDI_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync default:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return DDI_FAILURE;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync }
332ccb6ac6feb4b50ec24d63ff029119164182ffvboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * Detach entry point, to detach a device to the system or suspend it.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDip The module structure instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param enmCmd Attach type (ddi_attach_cmd_t)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync *
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * @return corresponding solaris error code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME "::Detach\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync switch (enmCmd)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case DDI_DETACH:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync VBoxGuestSolarisRemoveIRQ(pDip);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ddi_regs_map_free(&g_PciIOHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ddi_regs_map_free(&g_PciMMIOHandle);
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync ddi_remove_minor_node(pDip, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTR0Term();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return DDI_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync case DDI_SUSPEND:
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync {
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync /** @todo implement suspend for guest driver. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return DDI_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d45f7f7fe0c28b500b45b2dc88d7a04f4c0be6b8vboxsync default:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return DDI_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync * Info entry point, called by solaris kernel for obtaining driver info.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDip The module structure instance (do not use).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param enmCmd Information request type.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pvArg Type specific argument.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param ppvResult Where to store the requested info.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return corresponding solaris error code.
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pvArg, void **ppvResult)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync LogFlow((DEVICE_NAME "::GetInfo\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = DDI_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync switch (enmCmd)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case DDI_INFO_DEVT2DEVINFO:
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync *ppvResult = (void *)g_pDip;
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case DDI_INFO_DEVT2INSTANCE:
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync *ppvResult = (void *)(uintptr_t)ddi_get_instance(g_pDip);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync default:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = DDI_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NOREF(pvArg);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * User context entry points
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsyncstatic int VBoxGuestSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync PVBOXGUESTSESSION pSession = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME "::Open\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync * Verify we are being opened as a character device.
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync */
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync if (fType != OTYP_CHR)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync return EINVAL;
04a471b98d492ee51b1f40424c7f90ddf44a90f0vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxguest_state_t *pState = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unsigned iOpenInstance;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
bee1a7d4b183cab9654f247b3ea8cf680842bed5vboxsync if ( !ddi_get_soft_state(g_pVBoxGuestSolarisState, iOpenInstance) /* faster */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync && ddi_soft_state_zalloc(g_pVBoxGuestSolarisState, iOpenInstance) == DDI_SUCCESS)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync {
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, iOpenInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pState)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync {
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync Log((DEVICE_NAME "::Open: too many open instances."));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return ENXIO;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Create a new session.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync rc = VBoxGuestCreateUserSession(&g_DevExt, &pSession);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync pState->pvProcRef = proc_ref();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pState->pSession = pSession;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pDev = makedevice(getmajor(*pDev), iOpenInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log((DEVICE_NAME "::Open: pSession=%p pState=%p pid=%d\n", pSession, pState, (int)RTProcSelf()));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync /* Failed, clean up. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ddi_soft_state_free(g_pVBoxGuestSolarisState, iOpenInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::Open: VBoxGuestCreateUserSession failed. rc=%d\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return EFAULT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisClose(dev_t Dev, int flag, int fType, cred_t *pCred)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d45f7f7fe0c28b500b45b2dc88d7a04f4c0be6b8vboxsync LogFlow((DEVICE_NAME "::Close pid=%d\n", (int)RTProcSelf()));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXGUESTSESSION pSession = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, getminor(Dev));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pState)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log((DEVICE_NAME "::Close: failed to get pState.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return EFAULT;
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync proc_unref(pState->pvProcRef);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSession = pState->pSession;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pState->pSession = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log((DEVICE_NAME "::Close: pSession=%p pState=%p\n", pSession, pState));
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync ddi_soft_state_free(g_pVBoxGuestSolarisState, getminor(Dev));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pSession)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync Log((DEVICE_NAME "::Close: failed to get pSession.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return EFAULT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Close the session.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxGuestCloseSession(&g_DevExt, pSession);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return 0;
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync}
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME "::Read\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, getminor(Dev));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pState)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log((DEVICE_NAME "::Close: failed to get pState.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return EFAULT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXGUESTSESSION pSession = pState->pSession;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (pSession->u32MousePosChangedSeq != u32CurSeq)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync pSession->u32MousePosChangedSeq = u32CurSeq;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return 0;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME "::Write\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @def IOCPARM_LEN
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Gets the length from the ioctl number.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This is normally defined by sys/ioccom.h on BSD systems...
ebe05ec36d1fcd24d62e7066dedcb4eb2e691358vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef IOCPARM_LEN
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# define IOCPARM_LEN(Code) (((Code) >> 16) & IOCPARM_MASK)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Driver ioctl, an alternate entry point for this character driver.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param Dev Device number
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param Cmd Operation identifier
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pArg Arguments from user to driver
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * @param Mode Information bitfield (read/write, address space etc.)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pCred User credentials
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVal Return value for calling process.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return corresponding solaris error code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync LogFlow((DEVICE_NAME ":VBoxGuestSolarisIOCtl\n"));
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync /*
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync * Get the session from the soft state item.
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync */
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, getminor(Dev));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pState)
f5395a2af3050ddd694b0ad505975f7b717ab4f1vboxsync {
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync LogRel((DEVICE_NAME "::IOCtl: no state data for %d\n", getminor(Dev)));
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync return EINVAL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXGUESTSESSION pSession = pState->pSession;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pSession)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync {
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync LogRel((DEVICE_NAME "::IOCtl: no session data for %d\n", getminor(Dev)));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return EINVAL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync /*
332ccb6ac6feb4b50ec24d63ff029119164182ffvboxsync * Read and validate the request wrapper.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBGLBIGREQ ReqWrap;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (IOCPARM_LEN(Cmd) != sizeof(ReqWrap))
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync LogRel((DEVICE_NAME "::IOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap)));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return ENOTTY;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = ddi_copyin((void *)pArg, &ReqWrap, sizeof(ReqWrap), Mode);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_UNLIKELY(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync LogRel((DEVICE_NAME "::IOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%d.\n", pArg, Cmd, rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return EINVAL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (ReqWrap.u32Magic != VBGLBIGREQ_MAGIC)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: bad magic %#x; pArg=%p Cmd=%d.\n", ReqWrap.u32Magic, pArg, Cmd));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return EINVAL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync if (RT_UNLIKELY( ReqWrap.cbData == 0
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync || ReqWrap.cbData > _1M*16))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: bad size %#x; pArg=%p Cmd=%d.\n", ReqWrap.cbData, pArg, Cmd));
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync return EINVAL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Read the request.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync void *pvBuf = RTMemTmpAlloc(ReqWrap.cbData);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_UNLIKELY(!pvBuf))
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap.cbData));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return ENOMEM;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_copyin((void *)(uintptr_t)ReqWrap.pvDataR3, pvBuf, ReqWrap.cbData, Mode);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_UNLIKELY(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTMemTmpFree(pvBuf);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return EFAULT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_UNLIKELY( ReqWrap.cbData != 0
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && !VALID_PTR(pvBuf)))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync RTMemTmpFree(pvBuf);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: pvBuf invalid pointer %p\n", pvBuf));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return EINVAL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log((DEVICE_NAME "::IOCtl: pSession=%p pid=%d.\n", pSession, (int)RTProcSelf()));
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Process the IOCtl.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync size_t cbDataReturned;
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync rc = VBoxGuestCommonIOCtl(Cmd, &g_DevExt, pSession, pvBuf, ReqWrap.cbData, &cbDataReturned);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_UNLIKELY(cbDataReturned > ReqWrap.cbData))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbDataReturned = ReqWrap.cbData;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (cbDataReturned > 0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_copyout(pvBuf, (void *)(uintptr_t)ReqWrap.pvDataR3, cbDataReturned, Mode);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_UNLIKELY(rc))
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: ddi_copyout failed; pvBuf=%p pArg=%p cbDataReturned=%u Cmd=%d. rc=%d\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pvBuf, pArg, cbDataReturned, Cmd, rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = EFAULT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME "::IOCtl: VBoxGuestCommonIOCtl failed. rc=%d\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTErrConvertToErrno(rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pVal = rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTMemTmpFree(pvBuf);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisPoll(dev_t Dev, short fEvents, int fAnyYet, short *pReqEvents, struct pollhead **ppPollHead)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME "::Poll: fEvents=%d fAnyYet=%d\n", fEvents, fAnyYet));
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, getminor(Dev));
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync if (RT_LIKELY(pState))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pState->pSession;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pSession->u32MousePosChangedSeq != u32CurSeq)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync *pReqEvents |= (POLLIN | POLLRDNORM);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSession->u32MousePosChangedSeq = u32CurSeq;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync *pReqEvents = 0;
1df4b0cdc5ec23d817014f9347ef28222b51e3fbvboxsync if (!fAnyYet)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync *ppPollHead = &g_PollHead;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
1df4b0cdc5ec23d817014f9347ef28222b51e3fbvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync Log((DEVICE_NAME "::Poll: no state data for %d\n", getminor(Dev)));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return EINVAL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Sets IRQ for VMMDev.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns Solaris error code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDip Pointer to the device info structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int VBoxGuestSolarisAddIRQ(dev_info_t *pDip)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow((DEVICE_NAME "::AddIRQ: pDip=%p\n", pDip));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int IntrType = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = ddi_intr_get_supported_types(pDip, &IntrType);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (rc == DDI_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync /* We won't need to bother about MSIs. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (IntrType & DDI_INTR_TYPE_FIXED)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int IntrCount = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_intr_get_nintrs(pDip, IntrType, &IntrCount);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( rc == DDI_SUCCESS
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync && IntrCount > 0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync int IntrAvail = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_intr_get_navail(pDip, IntrType, &IntrAvail);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( rc == DDI_SUCCESS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && IntrAvail > 0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync /* Allocated kernel memory for the interrupt handles. The allocation size is stored internally. */
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync g_pIntr = RTMemAlloc(IntrCount * sizeof(ddi_intr_handle_t));
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync if (g_pIntr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync int IntrAllocated;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_intr_alloc(pDip, g_pIntr, IntrType, 0, IntrCount, &IntrAllocated, DDI_INTR_ALLOC_NORMAL);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if ( rc == DDI_SUCCESS
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync && IntrAllocated > 0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync g_cIntrAllocated = IntrAllocated;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint_t uIntrPriority;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_intr_get_pri(g_pIntr[0], &uIntrPriority);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (rc == DDI_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Initialize the mutex. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mutex_init(&g_IrqMtx, NULL, MUTEX_DRIVER, DDI_INTR_PRI(uIntrPriority));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Assign interrupt handler functions and enable interrupts. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (int i = 0; i < IntrAllocated; i++)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_intr_add_handler(g_pIntr[i], (ddi_intr_handler_t *)VBoxGuestSolarisISR,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NULL /* No Private Data */, NULL);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (rc == DDI_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_intr_enable(g_pIntr[i]);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (rc != DDI_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Changing local IntrAllocated to hold so-far allocated handles for freeing. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IntrAllocated = i;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (rc == DDI_SUCCESS)
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync return rc;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Remove any assigned handlers */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel((DEVICE_NAME ":failed to assign IRQs allocated=%d\n", IntrAllocated));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (int x = 0; x < IntrAllocated; x++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ddi_intr_remove_handler(g_pIntr[x]);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get priority of interrupt. rc=%d\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Remove allocated IRQs, too bad we can free only one handle at a time. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (int k = 0; k < g_cIntrAllocated; k++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ddi_intr_free(g_pIntr[k]);
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
ab0130d1627b2b214952b929de71b89e4ba41eb1vboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to allocated IRQs. count=%d\n", IntrCount));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTMemFree(g_pIntr);
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync }
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync else
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to allocated IRQs. count=%d\n", IntrCount));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get or insufficient available IRQs. rc=%d IntrAvail=%d\n", rc, IntrAvail));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync else
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get or insufficient number of IRQs. rc=%d IntrCount=%d\n", rc, IntrCount));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync else
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync LogRel((DEVICE_NAME "::AddIRQ: invalid irq type. IntrType=%#x\n", IntrType));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync else
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync LogRel((DEVICE_NAME "::AddIRQ: failed to get supported interrupt types\n"));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync return rc;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync}
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Removes IRQ for VMMDev.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync * @param pDip Pointer to the device info structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsyncstatic void VBoxGuestSolarisRemoveIRQ(dev_info_t *pDip)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync LogFlow((DEVICE_NAME "::RemoveIRQ:\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (int i = 0; i < g_cIntrAllocated; i++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync int rc = ddi_intr_disable(g_pIntr[i]);
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync if (rc == DDI_SUCCESS)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ddi_intr_remove_handler(g_pIntr[i]);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (rc == DDI_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ddi_intr_free(g_pIntr[i]);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTMemFree(g_pIntr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mutex_destroy(&g_IrqMtx);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Interrupt Service Routine for VMMDev.
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync *
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync * @param Arg Private data (unused, will be NULL).
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync * @returns DDI_INTR_CLAIMED if it's our interrupt, DDI_INTR_UNCLAIMED if it isn't.
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic uint_t VBoxGuestSolarisISR(caddr_t Arg)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync LogFlow((DEVICE_NAME "::ISR:\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mutex_enter(&g_IrqMtx);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool fOurIRQ = VBoxGuestCommonISR(&g_DevExt);
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync mutex_exit(&g_IrqMtx);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fOurIRQ ? DDI_INTR_CLAIMED : DDI_INTR_UNCLAIMED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync LogFlow((DEVICE_NAME "::NativeISRMousePollEvent:\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Wake up poll waiters.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pollwakeup(&g_PollHead, POLLIN | POLLRDNORM);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* Common code that depend on g_DevExt. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "VBoxGuestIDC-unix.c.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync